@nauth-toolkit/mfa-passkey 0.1.13 → 0.1.17
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.
- package/dist/nestjs/index.d.ts +5 -0
- package/dist/nestjs/index.d.ts.map +1 -1
- package/dist/nestjs/index.js +6 -0
- package/dist/nestjs/index.js.map +1 -1
- package/dist/nestjs/passkey-mfa.module.d.ts +22 -0
- package/dist/nestjs/passkey-mfa.module.d.ts.map +1 -1
- package/dist/nestjs/passkey-mfa.module.js +29 -1
- package/dist/nestjs/passkey-mfa.module.js.map +1 -1
- package/dist/src/dto/mfa.dto.d.ts +476 -0
- package/dist/src/dto/mfa.dto.d.ts.map +1 -1
- package/dist/src/dto/mfa.dto.js +9 -0
- package/dist/src/dto/mfa.dto.js.map +1 -1
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +6 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/passkey-mfa-provider.service.d.ts +103 -1
- package/dist/src/passkey-mfa-provider.service.d.ts.map +1 -1
- package/dist/src/passkey-mfa-provider.service.js +133 -2
- package/dist/src/passkey-mfa-provider.service.js.map +1 -1
- package/dist/src/passkey.service.d.ts +62 -0
- package/dist/src/passkey.service.d.ts.map +1 -1
- package/dist/src/passkey.service.js +83 -2
- package/dist/src/passkey.service.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -3,6 +3,17 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.PasskeyService = void 0;
|
|
4
4
|
const server_1 = require("@simplewebauthn/server");
|
|
5
5
|
const core_1 = require("@nauth-toolkit/core");
|
|
6
|
+
/**
|
|
7
|
+
* Passkey Service (WebAuthn/FIDO2)
|
|
8
|
+
*
|
|
9
|
+
* Handles passkey authentication with proper platform authenticator support.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const options = await passkeyService.generateRegistrationOptions(user, existingDevices);
|
|
14
|
+
* const verified = await passkeyService.verifyRegistration(credential, challenge, transports);
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
6
17
|
class PasskeyService {
|
|
7
18
|
config;
|
|
8
19
|
logger;
|
|
@@ -14,11 +25,19 @@ class PasskeyService {
|
|
|
14
25
|
this.config = config;
|
|
15
26
|
this.logger = logger;
|
|
16
27
|
}
|
|
28
|
+
/**
|
|
29
|
+
* Get passkey configuration with defaults
|
|
30
|
+
*
|
|
31
|
+
* @returns Complete passkey configuration
|
|
32
|
+
* @throws {NAuthException} If required config is missing
|
|
33
|
+
* @private
|
|
34
|
+
*/
|
|
17
35
|
getPasskeyConfig() {
|
|
18
36
|
const passkeyConfig = this.config.mfa?.passkey;
|
|
19
37
|
if (!passkeyConfig?.rpName || !passkeyConfig?.rpId) {
|
|
20
38
|
throw new core_1.NAuthException(core_1.AuthErrorCode.VALIDATION_FAILED, 'Passkey configuration (rpName, rpId) is required');
|
|
21
39
|
}
|
|
40
|
+
// Use configured origin or default based on RP ID
|
|
22
41
|
let origin = passkeyConfig.origin;
|
|
23
42
|
if (!origin) {
|
|
24
43
|
origin = passkeyConfig.rpId === 'localhost' ? 'http://localhost:4200' : `https://${passkeyConfig.rpId}`;
|
|
@@ -29,9 +48,19 @@ class PasskeyService {
|
|
|
29
48
|
origin,
|
|
30
49
|
};
|
|
31
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Generate WebAuthn registration options for passkey setup
|
|
53
|
+
*
|
|
54
|
+
* @param userId - User ID (will be encoded as user.id)
|
|
55
|
+
* @param userEmail - User's email
|
|
56
|
+
* @param userName - User's display name
|
|
57
|
+
* @param existingDevices - User's existing passkey devices (to exclude from registration)
|
|
58
|
+
* @returns Registration options for WebAuthn API
|
|
59
|
+
*/
|
|
32
60
|
async generateRegistrationOptions(userId, userEmail, userName, existingDevices = []) {
|
|
33
61
|
this.logger?.log?.(`Generating passkey registration options for user: ${userEmail}`);
|
|
34
62
|
const passkeyConfig = this.getPasskeyConfig();
|
|
63
|
+
// Extract existing credential IDs to exclude from new registration
|
|
35
64
|
const excludeCredentials = existingDevices
|
|
36
65
|
.filter((device) => device.type === core_1.MFAMethod.PASSKEY && device.isActive && device.credentialId)
|
|
37
66
|
.map((device) => ({
|
|
@@ -53,13 +82,22 @@ class PasskeyService {
|
|
|
53
82
|
requireResidentKey: false,
|
|
54
83
|
userVerification: passkeyConfig.userVerification,
|
|
55
84
|
},
|
|
56
|
-
supportedAlgorithmIDs: [-7, -257],
|
|
85
|
+
supportedAlgorithmIDs: [-7, -257], // ES256, RS256
|
|
57
86
|
});
|
|
58
87
|
this.logger?.log?.(`Passkey registration options generated for: ${userEmail}`);
|
|
59
88
|
return {
|
|
60
89
|
options: options,
|
|
61
90
|
};
|
|
62
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Verify passkey registration response
|
|
94
|
+
*
|
|
95
|
+
* @param credential - WebAuthn registration response from client
|
|
96
|
+
* @param expectedChallenge - Expected challenge from registration options
|
|
97
|
+
* @param transports - Optional transports from client-side credential.getTransports()
|
|
98
|
+
* @returns Verified credential data for storage
|
|
99
|
+
* @throws {NAuthException} If verification fails
|
|
100
|
+
*/
|
|
63
101
|
async verifyRegistration(credential, expectedChallenge, transports) {
|
|
64
102
|
this.logger?.log?.('Verifying passkey registration');
|
|
65
103
|
const passkeyConfig = this.getPasskeyConfig();
|
|
@@ -86,6 +124,7 @@ class PasskeyService {
|
|
|
86
124
|
throw new core_1.NAuthException(core_1.AuthErrorCode.VALIDATION_FAILED, 'Passkey registration failed verification');
|
|
87
125
|
}
|
|
88
126
|
const { credentialID, credentialPublicKey, counter } = verification.registrationInfo;
|
|
127
|
+
// Use client-provided transports or try to extract from verification
|
|
89
128
|
let finalTransports = transports || [];
|
|
90
129
|
if (finalTransports.length === 0) {
|
|
91
130
|
const verifUnknown = verification;
|
|
@@ -94,7 +133,10 @@ class PasskeyService {
|
|
|
94
133
|
finalTransports = regInfo.transports;
|
|
95
134
|
}
|
|
96
135
|
}
|
|
136
|
+
// Extract credential ID - Use the ID from frontend directly for consistency
|
|
137
|
+
// This ensures it matches exactly what the browser will send during authentication
|
|
97
138
|
const frontendCredentialId = credential.id || credential.rawId;
|
|
139
|
+
// Fallback to SimpleWebAuthn's extracted ID if frontend ID not available
|
|
98
140
|
let storedCredentialId;
|
|
99
141
|
if (frontendCredentialId) {
|
|
100
142
|
storedCredentialId = frontendCredentialId;
|
|
@@ -111,23 +153,36 @@ class PasskeyService {
|
|
|
111
153
|
});
|
|
112
154
|
return {
|
|
113
155
|
verified: true,
|
|
114
|
-
credentialId: storedCredentialId,
|
|
156
|
+
credentialId: storedCredentialId, // Use frontend ID to ensure match during authentication
|
|
115
157
|
publicKey: Buffer.from(credentialPublicKey).toString('base64url'),
|
|
116
158
|
counter,
|
|
117
159
|
transports: finalTransports,
|
|
118
160
|
};
|
|
119
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* Generate WebAuthn authentication options for MFA challenge
|
|
164
|
+
*
|
|
165
|
+
* @param userDevices - User's registered passkey devices
|
|
166
|
+
* @returns Authentication options for WebAuthn API
|
|
167
|
+
*/
|
|
120
168
|
async generateAuthenticationOptions(userDevices) {
|
|
121
169
|
this.logger?.log?.('Generating passkey authentication options');
|
|
122
170
|
const passkeyConfig = this.getPasskeyConfig();
|
|
171
|
+
// Extract active passkey credentials
|
|
172
|
+
// Important: credentialId from database may be base64 or base64url
|
|
173
|
+
// SimpleWebAuthn expects base64url, so we use it as-is if it's already base64url
|
|
174
|
+
// If it's standard base64, we need to convert it
|
|
123
175
|
const allowCredentials = userDevices
|
|
124
176
|
.filter((device) => device.type === core_1.MFAMethod.PASSKEY && device.isActive && device.credentialId)
|
|
125
177
|
.map((device) => {
|
|
126
178
|
let credentialId = device.credentialId;
|
|
179
|
+
// Check if it's standard base64 (contains + or /) and convert to base64url
|
|
127
180
|
if (credentialId.includes('+') || credentialId.includes('/')) {
|
|
181
|
+
// It's standard base64, decode and re-encode as base64url
|
|
128
182
|
const decoded = Buffer.from(credentialId, 'base64');
|
|
129
183
|
credentialId = decoded.toString('base64url');
|
|
130
184
|
}
|
|
185
|
+
// Otherwise assume it's already base64url
|
|
131
186
|
return {
|
|
132
187
|
id: credentialId,
|
|
133
188
|
type: 'public-key',
|
|
@@ -148,6 +203,15 @@ class PasskeyService {
|
|
|
148
203
|
options: options,
|
|
149
204
|
};
|
|
150
205
|
}
|
|
206
|
+
/**
|
|
207
|
+
* Verify passkey authentication response
|
|
208
|
+
*
|
|
209
|
+
* @param credential - WebAuthn authentication response from client
|
|
210
|
+
* @param expectedChallenge - Expected challenge from authentication options
|
|
211
|
+
* @param device - MFA device with stored public key and counter
|
|
212
|
+
* @returns Verification result with new counter
|
|
213
|
+
* @throws {NAuthException} If verification fails
|
|
214
|
+
*/
|
|
151
215
|
async verifyAuthentication(credential, expectedChallenge, device) {
|
|
152
216
|
this.logger?.log?.(`Verifying passkey authentication for device: ${device.name}`);
|
|
153
217
|
if (!device.credentialId || !device.publicKey || device.counter === null || device.counter === undefined) {
|
|
@@ -156,18 +220,24 @@ class PasskeyService {
|
|
|
156
220
|
const passkeyConfig = this.getPasskeyConfig();
|
|
157
221
|
let verification;
|
|
158
222
|
try {
|
|
223
|
+
// Convert base64url credential ID to Buffer
|
|
224
|
+
// Note: Database may store as base64 or base64url, try both formats
|
|
159
225
|
let credentialIDBuffer;
|
|
160
226
|
try {
|
|
227
|
+
// Try base64url first (current format)
|
|
161
228
|
credentialIDBuffer = Buffer.from(device.credentialId, 'base64url');
|
|
162
229
|
}
|
|
163
230
|
catch {
|
|
231
|
+
// Fallback to standard base64 (legacy format)
|
|
164
232
|
credentialIDBuffer = Buffer.from(device.credentialId, 'base64');
|
|
165
233
|
}
|
|
166
234
|
let publicKeyBuffer;
|
|
167
235
|
try {
|
|
236
|
+
// Try base64url first (current format)
|
|
168
237
|
publicKeyBuffer = Buffer.from(device.publicKey, 'base64url');
|
|
169
238
|
}
|
|
170
239
|
catch {
|
|
240
|
+
// Fallback to standard base64 (legacy format)
|
|
171
241
|
publicKeyBuffer = Buffer.from(device.publicKey, 'base64');
|
|
172
242
|
}
|
|
173
243
|
verification = await (0, server_1.verifyAuthenticationResponse)({
|
|
@@ -202,6 +272,11 @@ class PasskeyService {
|
|
|
202
272
|
newCounter: verification.authenticationInfo.newCounter,
|
|
203
273
|
};
|
|
204
274
|
}
|
|
275
|
+
/**
|
|
276
|
+
* Check if passkey is supported by configuration
|
|
277
|
+
*
|
|
278
|
+
* @returns True if passkey is properly configured
|
|
279
|
+
*/
|
|
205
280
|
isSupported() {
|
|
206
281
|
try {
|
|
207
282
|
this.getPasskeyConfig();
|
|
@@ -211,6 +286,12 @@ class PasskeyService {
|
|
|
211
286
|
return false;
|
|
212
287
|
}
|
|
213
288
|
}
|
|
289
|
+
/**
|
|
290
|
+
* Mask credential ID for display
|
|
291
|
+
*
|
|
292
|
+
* @param credentialId - Base64url encoded credential ID
|
|
293
|
+
* @returns Masked credential ID
|
|
294
|
+
*/
|
|
214
295
|
maskCredentialId(credentialId) {
|
|
215
296
|
if (credentialId.length <= 8) {
|
|
216
297
|
return credentialId;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"passkey.service.js","sourceRoot":"","sources":["../../src/passkey.service.ts"],"names":[],"mappings":";;;AAAA,mDAOgC;AAMhC,8CAQ6B;
|
|
1
|
+
{"version":3,"file":"passkey.service.js","sourceRoot":"","sources":["../../src/passkey.service.ts"],"names":[],"mappings":"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"}
|