@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.
|
|
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 ./",
|