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

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.
@@ -448,6 +448,12 @@ class ApiServer {
448
448
  }
449
449
  return this.passkeyServiceAdapter;
450
450
  }
451
+ async listUserCredentials(userId) {
452
+ return this.ensurePasskeyService().listUserCredentials(userId);
453
+ }
454
+ async deletePasskeyCredential(credentialId) {
455
+ return this.ensurePasskeyService().deleteCredential(credentialId);
456
+ }
451
457
  ensureOAuthStore() {
452
458
  if (!this.oauthStoreAdapter) {
453
459
  throw new Error('OAuth store is not configured');
@@ -13,7 +13,7 @@ import type { AuthAdapter, AuthIdentifier } from './auth-api/types.js';
13
13
  import type { OAuthStore } from './oauth/base.js';
14
14
  import type { AuthCodeData, AuthCodeRequest, OAuthClient } from './oauth/types.js';
15
15
  import type { PasskeyService } from './passkey/service.js';
16
- import type { PasskeyChallenge, PasskeyChallengeParams, PasskeyVerificationParams, PasskeyVerificationResult } from './passkey/types.js';
16
+ import type { PasskeyChallenge, PasskeyChallengeParams, StoredPasskeyCredential, PasskeyVerificationParams, PasskeyVerificationResult } from './passkey/types.js';
17
17
  import type { Token } from './token/types.js';
18
18
  import type { UserStore } from './user/base.js';
19
19
  import type { JwtPayload, SignOptions, VerifyOptions } from 'jsonwebtoken';
@@ -139,6 +139,8 @@ export declare class ApiServer {
139
139
  private ensureUserStore;
140
140
  private ensureTokenStore;
141
141
  private ensurePasskeyService;
142
+ listUserCredentials(userId: AuthIdentifier): Promise<StoredPasskeyCredential[]>;
143
+ deletePasskeyCredential(credentialId: Buffer | string): Promise<boolean>;
142
144
  private ensureOAuthStore;
143
145
  getUser(identifier: AuthIdentifier): Promise<any | null>;
144
146
  getUserPasswordHash(user: any): string;
@@ -113,7 +113,8 @@ class PasskeyService {
113
113
  return {
114
114
  challenge: options.challenge,
115
115
  expiresAt: expiresAt.toISOString(),
116
- userId: user.id
116
+ userId: user.id,
117
+ publicKey: options
117
118
  };
118
119
  }
119
120
  async createAuthenticationChallenge(params, metadata) {
@@ -142,7 +143,8 @@ class PasskeyService {
142
143
  return {
143
144
  challenge: options.challenge,
144
145
  expiresAt: expiresAt.toISOString(),
145
- userId: user.id
146
+ userId: user.id,
147
+ publicKey: options
146
148
  };
147
149
  }
148
150
  async verifyRegistration(params, record) {
@@ -161,6 +163,10 @@ class PasskeyService {
161
163
  requireUserVerification: true
162
164
  });
163
165
  if (!result.verified || !result.registrationInfo) {
166
+ if (!result.verified) {
167
+ const err = result.error ?? result;
168
+ this.logger.error?.('Passkey registration verification failed', err);
169
+ }
164
170
  return { verified: false };
165
171
  }
166
172
  const registrationInfo = result.registrationInfo;
@@ -204,6 +210,8 @@ class PasskeyService {
204
210
  requireUserVerification: true
205
211
  });
206
212
  if (!result.verified) {
213
+ const err = result.error ?? result;
214
+ this.logger.error?.('Passkey authentication verification failed', err);
207
215
  return { verified: false };
208
216
  }
209
217
  await this.adapter.updateCredentialCounter(credential.credentialId, result.authenticationInfo.newCounter);
@@ -13,7 +13,7 @@ import type { AuthAdapter, AuthIdentifier } from './auth-api/types.js';
13
13
  import type { OAuthStore } from './oauth/base.js';
14
14
  import type { AuthCodeData, AuthCodeRequest, OAuthClient } from './oauth/types.js';
15
15
  import type { PasskeyService } from './passkey/service.js';
16
- import type { PasskeyChallenge, PasskeyChallengeParams, PasskeyVerificationParams, PasskeyVerificationResult } from './passkey/types.js';
16
+ import type { PasskeyChallenge, PasskeyChallengeParams, StoredPasskeyCredential, PasskeyVerificationParams, PasskeyVerificationResult } from './passkey/types.js';
17
17
  import type { Token } from './token/types.js';
18
18
  import type { UserStore } from './user/base.js';
19
19
  import type { JwtPayload, SignOptions, VerifyOptions } from 'jsonwebtoken';
@@ -139,6 +139,8 @@ export declare class ApiServer {
139
139
  private ensureUserStore;
140
140
  private ensureTokenStore;
141
141
  private ensurePasskeyService;
142
+ listUserCredentials(userId: AuthIdentifier): Promise<StoredPasskeyCredential[]>;
143
+ deletePasskeyCredential(credentialId: Buffer | string): Promise<boolean>;
142
144
  private ensureOAuthStore;
143
145
  getUser(identifier: AuthIdentifier): Promise<any | null>;
144
146
  getUserPasswordHash(user: any): string;
@@ -440,6 +440,12 @@ export class ApiServer {
440
440
  }
441
441
  return this.passkeyServiceAdapter;
442
442
  }
443
+ async listUserCredentials(userId) {
444
+ return this.ensurePasskeyService().listUserCredentials(userId);
445
+ }
446
+ async deletePasskeyCredential(credentialId) {
447
+ return this.ensurePasskeyService().deleteCredential(credentialId);
448
+ }
443
449
  ensureOAuthStore() {
444
450
  if (!this.oauthStoreAdapter) {
445
451
  throw new Error('OAuth store is not configured');
@@ -110,7 +110,8 @@ export class PasskeyService {
110
110
  return {
111
111
  challenge: options.challenge,
112
112
  expiresAt: expiresAt.toISOString(),
113
- userId: user.id
113
+ userId: user.id,
114
+ publicKey: options
114
115
  };
115
116
  }
116
117
  async createAuthenticationChallenge(params, metadata) {
@@ -139,7 +140,8 @@ export class PasskeyService {
139
140
  return {
140
141
  challenge: options.challenge,
141
142
  expiresAt: expiresAt.toISOString(),
142
- userId: user.id
143
+ userId: user.id,
144
+ publicKey: options
143
145
  };
144
146
  }
145
147
  async verifyRegistration(params, record) {
@@ -158,6 +160,10 @@ export class PasskeyService {
158
160
  requireUserVerification: true
159
161
  });
160
162
  if (!result.verified || !result.registrationInfo) {
163
+ if (!result.verified) {
164
+ const err = result.error ?? result;
165
+ this.logger.error?.('Passkey registration verification failed', err);
166
+ }
161
167
  return { verified: false };
162
168
  }
163
169
  const registrationInfo = result.registrationInfo;
@@ -201,6 +207,8 @@ export class PasskeyService {
201
207
  requireUserVerification: true
202
208
  });
203
209
  if (!result.verified) {
210
+ const err = result.error ?? result;
211
+ this.logger.error?.('Passkey authentication verification failed', err);
204
212
  return { verified: false };
205
213
  }
206
214
  await this.adapter.updateCredentialCounter(credential.credentialId, result.authenticationInfo.newCounter);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@technomoron/api-server-base",
3
- "version": "2.0.0-beta.4",
3
+ "version": "2.0.0-beta.5",
4
4
  "description": "Api Server Skeleton / Base Class",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.cjs",
@@ -30,6 +30,8 @@
30
30
  "build:esm": "tsc --project tsconfig/tsconfig.esm.json",
31
31
  "build": "node scripts/run-builds.cjs",
32
32
  "test": "vitest run",
33
+ "test:unit": "vitest run tests/unit",
34
+ "test:functional": "vitest run tests/functional",
33
35
  "test:watch": "vitest --watch",
34
36
  "prepublishOnly": "node scripts/run-builds.cjs",
35
37
  "lint": "eslint --ext .js,.ts,.vue ./",