@prove-identity/prove-auth 2.7.1 → 2.9.0
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/README.md +8 -9
- package/build/bundle/release/prove-auth.js +1 -0
- package/build/lib/index.d.ts +3 -2
- package/build/lib/index.js +3 -1
- package/build/lib/proveauth/authenticator-builder.d.ts +4 -0
- package/build/lib/proveauth/authenticator-builder.js +59 -3
- package/build/lib/proveauth/darwinium-result.d.ts +11 -0
- package/build/lib/proveauth/darwinium-result.js +25 -0
- package/build/lib/proveauth/darwinium-wrapper.d.ts +6 -0
- package/build/lib/proveauth/darwinium-wrapper.js +97 -0
- package/build/lib/proveauth/device-context-options.d.ts +7 -0
- package/build/lib/proveauth/device-context-options.js +7 -1
- package/build/lib/proveauth/internal/auth-error.js +1 -1
- package/build/lib/proveauth/internal/auth-request.d.ts +1 -0
- package/build/lib/proveauth/internal/auth-response.d.ts +5 -1
- package/build/lib/proveauth/internal/auth-session.d.ts +7 -2
- package/build/lib/proveauth/internal/auth-session.js +115 -11
- package/build/lib/proveauth/internal/auth-status-actions.js +4 -4
- package/build/lib/proveauth/internal/auth-token-claims.d.ts +1 -0
- package/build/lib/proveauth/internal/device-auth.d.ts +3 -1
- package/build/lib/proveauth/internal/device-passive-register-step.d.ts +1 -0
- package/build/lib/proveauth/internal/device-passive-register-step.js +55 -35
- package/build/lib/proveauth/internal/device-passive-silent-step.js +9 -1
- package/build/lib/proveauth/internal/device-passive-step.d.ts +12 -4
- package/build/lib/proveauth/internal/device-passive-step.js +172 -52
- package/build/lib/proveauth/internal/device-passive-stepup-step.d.ts +2 -1
- package/build/lib/proveauth/internal/device-passive-stepup-step.js +25 -3
- package/build/lib/proveauth/internal/device-passive-verify-step.d.ts +3 -2
- package/build/lib/proveauth/internal/device-passive-verify-step.js +29 -10
- package/build/lib/proveauth/internal/fido-options-error.d.ts +30 -0
- package/build/lib/proveauth/internal/fido-options-error.js +161 -0
- package/build/lib/proveauth/internal/main-authenticator.js +1 -1
- package/build/lib/proveauth/internal/mobile-instantlink-step.js +36 -29
- package/build/lib/proveauth/internal/mobile-otp-step.d.ts +3 -0
- package/build/lib/proveauth/internal/mobile-otp-step.js +115 -67
- package/build/lib/proveauth/internal/platform.d.ts +2 -0
- package/build/lib/proveauth/internal/report-error-step.d.ts +1 -2
- package/build/lib/proveauth/internal/report-error-step.js +13 -12
- package/build/lib/proveauth/internal/scan-message-step.js +1 -1
- package/build/lib/proveauth/internal/settings.d.ts +4 -0
- package/build/lib/proveauth/internal/settings.js +16 -0
- package/build/lib/proveauth/internal/web-device-auth.d.ts +3 -1
- package/build/lib/proveauth/internal/web-device-auth.js +31 -15
- package/build/lib/proveauth/internal/web-platform.d.ts +2 -1
- package/build/lib/proveauth/internal/web-platform.js +19 -0
- package/build/lib/proveauth/internal/web-socket-close-reasons.d.ts +15 -0
- package/build/lib/proveauth/internal/web-socket-close-reasons.js +19 -0
- package/build/lib/proveauth/version.d.ts +2 -2
- package/build/lib/proveauth/version.js +2 -2
- package/package.json +1 -1
|
@@ -11,57 +11,51 @@ const auth_token_claims_1 = require("./auth-token-claims");
|
|
|
11
11
|
const auth_error_1 = __importDefault(require("./auth-error"));
|
|
12
12
|
const authenticator_builder_1 = require("../authenticator-builder");
|
|
13
13
|
const auth_status_actions_1 = require("./auth-status-actions");
|
|
14
|
+
const fido_options_error_1 = require("./fido-options-error");
|
|
15
|
+
const auth_response_status_1 = require("./auth-response-status");
|
|
14
16
|
class DevicePassiveActions extends auth_status_actions_1.AuthStatusActions {
|
|
15
|
-
constructor(getDisplayName) {
|
|
17
|
+
constructor(getDisplayName, handler) {
|
|
16
18
|
super();
|
|
17
19
|
this.log = logger_1.LoggerFactory.getLogger('device-passive-actions');
|
|
18
20
|
this.getDisplayName = getDisplayName ? getDisplayName : () => null;
|
|
21
|
+
this.handler = handler;
|
|
19
22
|
}
|
|
20
|
-
register(session) {
|
|
21
|
-
this.log.trace('Registering');
|
|
23
|
+
register(session, signals) {
|
|
24
|
+
this.log.trace('Registering Passkey');
|
|
22
25
|
return new Promise((resolve, reject) => {
|
|
23
26
|
const displayName = this.getDisplayName();
|
|
24
27
|
session
|
|
25
28
|
.fetchFromBackend('/v1/client/device/fido2/register/start', {
|
|
26
29
|
displayName: displayName ? displayName : undefined,
|
|
30
|
+
signals: signals,
|
|
27
31
|
})
|
|
28
32
|
.then((response) => {
|
|
33
|
+
var _a, _b;
|
|
29
34
|
if (response.error) {
|
|
30
|
-
reject(new auth_error_1.default(response.error.message, response.error.code, response.next));
|
|
35
|
+
reject(new auth_error_1.default(response.error.message, response.error.code, response.next, false));
|
|
31
36
|
}
|
|
32
37
|
else {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
const creationOptions = (_a = response.data) === null || _a === void 0 ? void 0 : _a.credCreateOptions;
|
|
39
|
+
const requestOptions = (_b = response.data) === null || _b === void 0 ? void 0 : _b.credRequestOptions;
|
|
40
|
+
if (creationOptions) {
|
|
41
|
+
this.createCredentials(session, displayName, creationOptions, response)
|
|
42
|
+
.then(resolve)
|
|
43
|
+
.catch(reject);
|
|
44
|
+
}
|
|
45
|
+
else if (requestOptions) {
|
|
46
|
+
this.getCredentials(session, requestOptions, response).then(resolve).catch(reject);
|
|
38
47
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
});
|
|
48
|
+
else {
|
|
49
|
+
const error = new auth_error_1.default(DevicePassiveActions.NO_CREDS_FOUND);
|
|
50
|
+
reject(error);
|
|
43
51
|
}
|
|
44
|
-
session.platform.webauthn
|
|
45
|
-
.createCredentials({
|
|
46
|
-
publicKey: options,
|
|
47
|
-
})
|
|
48
|
-
.then((credential) => {
|
|
49
|
-
if (!credential) {
|
|
50
|
-
reject(new auth_error_1.default('Failed to create FIDO2 credentials'));
|
|
51
|
-
}
|
|
52
|
-
else {
|
|
53
|
-
session.credential = credential;
|
|
54
|
-
resolve(response.next);
|
|
55
|
-
}
|
|
56
|
-
})
|
|
57
|
-
.catch(reject);
|
|
58
52
|
}
|
|
59
53
|
})
|
|
60
54
|
.catch(reject);
|
|
61
55
|
});
|
|
62
56
|
}
|
|
63
57
|
verify(session) {
|
|
64
|
-
this.log.trace('Verifying');
|
|
58
|
+
this.log.trace('Verifying Passkey');
|
|
65
59
|
return new Promise((resolve, reject) => {
|
|
66
60
|
if (session.settings.deviceId) {
|
|
67
61
|
session
|
|
@@ -69,46 +63,150 @@ class DevicePassiveActions extends auth_status_actions_1.AuthStatusActions {
|
|
|
69
63
|
deviceId: session.settings.deviceId,
|
|
70
64
|
})
|
|
71
65
|
.then((response) => {
|
|
72
|
-
var _a;
|
|
73
66
|
if (response.error) {
|
|
74
|
-
reject(new auth_error_1.default(response.error.message, response.error.code, response.next));
|
|
67
|
+
reject(new auth_error_1.default(response.error.message, response.error.code, response.next, false));
|
|
75
68
|
}
|
|
76
69
|
else {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
70
|
+
const options = response.data.credRequestOptions;
|
|
71
|
+
this.getCredentials(session, options, response).then(resolve).catch(reject);
|
|
72
|
+
}
|
|
73
|
+
})
|
|
74
|
+
.catch(reject);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
reject(new auth_error_1.default('Failed to start verification, DeviceId is missing'));
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
createCredentials(session, displayName, options, response) {
|
|
82
|
+
this.log.trace('Trying create new FIDO credentials');
|
|
83
|
+
return new Promise((resolve, reject) => {
|
|
84
|
+
options.challenge = base64_1.default.bufferDecode(options.challenge);
|
|
85
|
+
options.user.id = base64_1.default.bufferDecode(options.user.id);
|
|
86
|
+
if (displayName) {
|
|
87
|
+
options.user.displayName = displayName;
|
|
88
|
+
}
|
|
89
|
+
if (options.excludeCredentials) {
|
|
90
|
+
options.excludeCredentials.forEach((i) => {
|
|
91
|
+
i.id = base64_1.default.bufferDecode(i.id);
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
if (options.authenticatorSelection) {
|
|
95
|
+
options.authenticatorSelection.residentKey = 'preferred';
|
|
96
|
+
options.authenticatorSelection.requireResidentKey = false;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
options.authenticatorSelection = {
|
|
100
|
+
residentKey: 'preferred',
|
|
101
|
+
requireResidentKey: false,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
const fidoCreationOptions = {
|
|
105
|
+
publicKey: options,
|
|
106
|
+
};
|
|
107
|
+
session.platform.webauthn
|
|
108
|
+
.createCredentials(fidoCreationOptions)
|
|
109
|
+
.then((credential) => {
|
|
110
|
+
if (!credential) {
|
|
111
|
+
reject(new auth_error_1.default('Failed to create FIDO2 credentials'));
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
session.credential = credential;
|
|
115
|
+
resolve(response.next);
|
|
116
|
+
}
|
|
117
|
+
})
|
|
118
|
+
.catch((error) => {
|
|
119
|
+
const fidoCreationError = fido_options_error_1.FidoOptionsError.identifyRegistrationError({
|
|
120
|
+
error: error,
|
|
121
|
+
options: fidoCreationOptions,
|
|
122
|
+
platform: session.platform,
|
|
123
|
+
});
|
|
124
|
+
if (fidoCreationError instanceof fido_options_error_1.FidoOptionsError &&
|
|
125
|
+
fidoCreationError.name === 'InvalidStateError') {
|
|
126
|
+
if (this.handler) {
|
|
127
|
+
this.log.trace('Passkey handler callback has been defined');
|
|
128
|
+
this.handler()
|
|
129
|
+
.then((userResponse) => {
|
|
130
|
+
if (userResponse === auth_response_status_1.AuthResponseStatus.Accept) {
|
|
131
|
+
this.parseCredRequestOptions(response, session).then(resolve).catch(reject);
|
|
91
132
|
}
|
|
92
133
|
else {
|
|
93
|
-
|
|
94
|
-
|
|
134
|
+
reject(new auth_error_1.default(`${DevicePassiveActions.USER_NOT_ACCEPTING_RESPONSE}: ${userResponse}`));
|
|
135
|
+
return;
|
|
95
136
|
}
|
|
96
137
|
})
|
|
97
138
|
.catch(reject);
|
|
98
139
|
}
|
|
99
|
-
|
|
100
|
-
|
|
140
|
+
else {
|
|
141
|
+
this.log.trace('Passkey handler callback is null, go ahead with passkey discoverable as default behavior');
|
|
142
|
+
this.parseCredRequestOptions(response, session).then(resolve).catch(reject);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
reject(fidoCreationError);
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
parseCredRequestOptions(response, session) {
|
|
152
|
+
return new Promise((resolve, reject) => {
|
|
153
|
+
const data = response.data;
|
|
154
|
+
if (data.credRequestOptions) {
|
|
155
|
+
const requestOptions = data.credRequestOptions;
|
|
156
|
+
this.getCredentials(session, requestOptions, response).then(resolve).catch(reject);
|
|
101
157
|
}
|
|
102
158
|
else {
|
|
103
|
-
reject(new auth_error_1.default(
|
|
159
|
+
reject(new auth_error_1.default(DevicePassiveActions.NO_REQUEST_CREDS_FOUND));
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
getCredentials(session, options, response) {
|
|
164
|
+
this.log.trace('Trying get existing FIDO credentials');
|
|
165
|
+
return new Promise((resolve, reject) => {
|
|
166
|
+
var _a, _b;
|
|
167
|
+
if (((_a = options.allowCredentials) === null || _a === void 0 ? void 0 : _a.length) == 0) {
|
|
168
|
+
reject(new auth_error_1.default('AllowCredentials array should not be empty when call getCredentials()'));
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
options.challenge = base64_1.default.bufferDecode(options.challenge);
|
|
172
|
+
if (options.allowCredentials) {
|
|
173
|
+
(_b = options.allowCredentials) === null || _b === void 0 ? void 0 : _b.forEach((i) => {
|
|
174
|
+
i.id = base64_1.default.bufferDecode(i.id);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
const fidoRequestOptions = {
|
|
178
|
+
publicKey: options,
|
|
179
|
+
};
|
|
180
|
+
session.platform.webauthn
|
|
181
|
+
.getCredentials(fidoRequestOptions)
|
|
182
|
+
.then((credential) => {
|
|
183
|
+
if (!credential) {
|
|
184
|
+
reject(new auth_error_1.default('Failed to load FIDO2 credentials'));
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
session.credential = credential;
|
|
188
|
+
resolve(response.next);
|
|
189
|
+
}
|
|
190
|
+
})
|
|
191
|
+
.catch((error) => {
|
|
192
|
+
const fidoAuthenticationError = fido_options_error_1.FidoOptionsError.identifyAuthenticationError({
|
|
193
|
+
error: error,
|
|
194
|
+
options: fidoRequestOptions,
|
|
195
|
+
platform: session.platform,
|
|
196
|
+
});
|
|
197
|
+
reject(fidoAuthenticationError);
|
|
198
|
+
});
|
|
104
199
|
}
|
|
105
200
|
});
|
|
106
201
|
}
|
|
107
202
|
}
|
|
203
|
+
DevicePassiveActions.NO_REQUEST_CREDS_FOUND = 'Passkey has already been registered but found no CredentialRequestOptions in the fido/register/start response payload';
|
|
204
|
+
DevicePassiveActions.NO_CREDS_FOUND = 'Neither credCreateOptions nor credRequestOptions are found in the fido/register/start response payload';
|
|
205
|
+
DevicePassiveActions.USER_NOT_ACCEPTING_RESPONSE = 'User not accepting to continue by reusing the existing passkey with user response';
|
|
108
206
|
exports.DevicePassiveActions = DevicePassiveActions;
|
|
109
207
|
class DevicePassiveStep extends DevicePassiveActions {
|
|
110
|
-
constructor(getDisplayName, role) {
|
|
111
|
-
super(getDisplayName);
|
|
208
|
+
constructor(getDisplayName, handler, role) {
|
|
209
|
+
super(getDisplayName, handler);
|
|
112
210
|
this.name = DevicePassiveStep.NAME;
|
|
113
211
|
this.role = role !== null && role !== void 0 ? role : authenticator_builder_1.DeviceRole.Primary;
|
|
114
212
|
this.log = logger_1.LoggerFactory.getLogger('device-passive-step');
|
|
@@ -127,7 +225,29 @@ class DevicePassiveStep extends DevicePassiveActions {
|
|
|
127
225
|
}
|
|
128
226
|
return Promise.resolve(device_passive_silent_step_1.default.NAME);
|
|
129
227
|
}
|
|
130
|
-
return
|
|
228
|
+
return new Promise((resolve, reject) => {
|
|
229
|
+
session
|
|
230
|
+
.getFingerprintData()
|
|
231
|
+
.then((signal) => {
|
|
232
|
+
const signals = {
|
|
233
|
+
fingerprint: signal,
|
|
234
|
+
};
|
|
235
|
+
session.embedDarwiniumSignal(signals);
|
|
236
|
+
this.register(session, signals).then(resolve).catch(reject);
|
|
237
|
+
})
|
|
238
|
+
.catch((error) => {
|
|
239
|
+
const errorMsg = `Unexpected error happened during Fingerprint data collection: ${error.message}`;
|
|
240
|
+
this.log.warn(errorMsg);
|
|
241
|
+
this.log.warn(error);
|
|
242
|
+
const signals = {
|
|
243
|
+
fingerprint: {
|
|
244
|
+
error: errorMsg,
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
session.embedDarwiniumSignal(signals);
|
|
248
|
+
this.register(session, signals).then(resolve).catch(reject);
|
|
249
|
+
});
|
|
250
|
+
});
|
|
131
251
|
}
|
|
132
252
|
}
|
|
133
253
|
DevicePassiveStep.NAME = 'device/passive';
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { PasskeyAlreadyExistCallback } from '../authenticator-builder';
|
|
1
2
|
import AuthSession from './auth-session';
|
|
2
3
|
import AuthStep from './auth-step';
|
|
3
4
|
import { DevicePassiveActions } from './device-passive-step';
|
|
4
5
|
export default class DevicePassiveStepupStep extends DevicePassiveActions implements AuthStep {
|
|
5
6
|
static readonly NAME = "device/passive/stepup";
|
|
6
7
|
readonly name = "device/passive/stepup";
|
|
7
|
-
constructor(getDisplayName?: () => string | null);
|
|
8
|
+
constructor(getDisplayName?: () => string | null, handler?: PasskeyAlreadyExistCallback);
|
|
8
9
|
execute(session: AuthSession): Promise<string>;
|
|
9
10
|
}
|
|
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const logger_1 = require("../common/logger");
|
|
4
4
|
const device_passive_step_1 = require("./device-passive-step");
|
|
5
5
|
class DevicePassiveStepupStep extends device_passive_step_1.DevicePassiveActions {
|
|
6
|
-
constructor(getDisplayName) {
|
|
7
|
-
super(getDisplayName);
|
|
6
|
+
constructor(getDisplayName, handler) {
|
|
7
|
+
super(getDisplayName, handler);
|
|
8
8
|
this.name = DevicePassiveStepupStep.NAME;
|
|
9
9
|
this.log = logger_1.LoggerFactory.getLogger('device-passive-stepup-step');
|
|
10
10
|
}
|
|
@@ -18,7 +18,29 @@ class DevicePassiveStepupStep extends device_passive_step_1.DevicePassiveActions
|
|
|
18
18
|
if (session.settings.fidoPasskeyRegistered) {
|
|
19
19
|
return Promise.reject(new Error('FIDO2 Passkey is already registered'));
|
|
20
20
|
}
|
|
21
|
-
return
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
session
|
|
23
|
+
.getFingerprintData()
|
|
24
|
+
.then((signal) => {
|
|
25
|
+
const signals = {
|
|
26
|
+
fingerprint: signal,
|
|
27
|
+
};
|
|
28
|
+
session.embedDarwiniumSignal(signals);
|
|
29
|
+
this.register(session, signals).then(resolve).catch(reject);
|
|
30
|
+
})
|
|
31
|
+
.catch((error) => {
|
|
32
|
+
const errorMsg = `Unexpected error happened during Fingerprint data collection: ${error.message}`;
|
|
33
|
+
this.log.warn(errorMsg);
|
|
34
|
+
this.log.warn(error);
|
|
35
|
+
const signals = {
|
|
36
|
+
fingerprint: {
|
|
37
|
+
error: errorMsg,
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
session.embedDarwiniumSignal(signals);
|
|
41
|
+
this.register(session, signals).then(resolve).catch(reject);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
22
44
|
}
|
|
23
45
|
}
|
|
24
46
|
DevicePassiveStepupStep.NAME = 'device/passive/stepup';
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import AuthSession from './auth-session';
|
|
2
2
|
import AuthStep from './auth-step';
|
|
3
|
-
import {
|
|
3
|
+
import { Logger } from '../common/logger';
|
|
4
4
|
export default class DevicePassiveVerifyStep implements AuthStep {
|
|
5
5
|
static readonly NAME = "device/passive/verify";
|
|
6
6
|
private readonly log;
|
|
7
7
|
readonly name = "device/passive/verify";
|
|
8
8
|
execute(session: AuthSession): Promise<string>;
|
|
9
|
-
|
|
9
|
+
static runFidoVerify(log: Logger, session: AuthSession): Promise<string>;
|
|
10
|
+
private static makeFidoVerifyFinishRequest;
|
|
10
11
|
}
|
|
@@ -12,23 +12,33 @@ class DevicePassiveVerifyStep {
|
|
|
12
12
|
this.name = DevicePassiveVerifyStep.NAME;
|
|
13
13
|
}
|
|
14
14
|
execute(session) {
|
|
15
|
+
return new Promise((resolve, reject) => {
|
|
16
|
+
DevicePassiveVerifyStep.runFidoVerify(this.log, session).then(resolve).catch(reject);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
static runFidoVerify(log, session) {
|
|
15
20
|
return new Promise((resolve, reject) => {
|
|
16
21
|
session
|
|
17
22
|
.getFingerprintData()
|
|
18
23
|
.then((signal) => {
|
|
19
|
-
const signals =
|
|
20
|
-
|
|
24
|
+
const signals = { fingerprint: signal };
|
|
25
|
+
session.embedDarwiniumSignal(signals);
|
|
26
|
+
DevicePassiveVerifyStep.makeFidoVerifyFinishRequest(log, session, signals)
|
|
27
|
+
.then(resolve)
|
|
28
|
+
.catch(reject);
|
|
21
29
|
})
|
|
22
30
|
.catch((error) => {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
31
|
+
const errorMsg = `Unexpected error happened during Fingerprint data collection ${error.toString}`;
|
|
32
|
+
log.warn(errorMsg);
|
|
33
|
+
const signals = { fingerprint: { error: errorMsg } };
|
|
34
|
+
session.embedDarwiniumSignal(signals);
|
|
35
|
+
DevicePassiveVerifyStep.makeFidoVerifyFinishRequest(log, session, signals)
|
|
26
36
|
.then(resolve)
|
|
27
37
|
.catch(reject);
|
|
28
38
|
});
|
|
29
39
|
});
|
|
30
40
|
}
|
|
31
|
-
|
|
41
|
+
static makeFidoVerifyFinishRequest(log, session, signals) {
|
|
32
42
|
return new Promise((resolve, reject) => {
|
|
33
43
|
const credential = session.credential;
|
|
34
44
|
const assertion = credential.response;
|
|
@@ -51,16 +61,25 @@ class DevicePassiveVerifyStep {
|
|
|
51
61
|
})
|
|
52
62
|
.then((response) => {
|
|
53
63
|
if (response.error) {
|
|
54
|
-
reject(new auth_error_1.default(response.error.message, response.error.code, response.next));
|
|
64
|
+
reject(new auth_error_1.default(response.error.message, response.error.code, response.next, false));
|
|
55
65
|
}
|
|
56
66
|
else {
|
|
57
67
|
const data = response.data;
|
|
58
|
-
if (data
|
|
59
|
-
|
|
68
|
+
if (data) {
|
|
69
|
+
if (data.deviceId) {
|
|
70
|
+
session.settings.deviceId = data.deviceId;
|
|
71
|
+
}
|
|
72
|
+
if (data.passkey) {
|
|
73
|
+
session.settings.fidoPasskeyRegistered = true;
|
|
74
|
+
}
|
|
75
|
+
if (data.scanMessage) {
|
|
76
|
+
session.authMessage = data.scanMessage;
|
|
77
|
+
}
|
|
60
78
|
}
|
|
61
79
|
else {
|
|
62
|
-
|
|
80
|
+
log.warn('No data was received in the response');
|
|
63
81
|
}
|
|
82
|
+
session.settings.fidoPasskeyRegistered = true;
|
|
64
83
|
resolve(response.next);
|
|
65
84
|
}
|
|
66
85
|
})
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import Platform from './platform';
|
|
2
|
+
export declare class FidoOptionsError extends Error {
|
|
3
|
+
static readonly MISSING_PUBLIC_KEY_PROPERTY = "options missing publicKey property";
|
|
4
|
+
static readonly ABORT_SIGNAL = "Authentication was sent an abort signal";
|
|
5
|
+
static readonly INVALID_STATE_ERROR = "The authenticator was already registered";
|
|
6
|
+
static readonly UNKNOWN_ERROR = "Unknown error: the authenticator was unable to process the predefined options, or unable to generate a new credential";
|
|
7
|
+
static readonly SECURITY_ERROR_FOUND = "Security error found";
|
|
8
|
+
static readonly INVALID_RP_ID = "The rp.id is not valid for the current domain";
|
|
9
|
+
static readonly CONSTRAINT_ERROR = "Discoverable credentials is required but found no matching supported authenticator";
|
|
10
|
+
static readonly USER_VERIFICATION_NOT_POSSILE = "User verification is required during automatic registration but this could not be performed";
|
|
11
|
+
static readonly NO_MATCHING_AUTHENTICATOR = "User verification is required but found no matching supported authenticator";
|
|
12
|
+
static readonly INVALID_CRED_PARAMS = "No entry in pubKeyCredParams having the type of public-key";
|
|
13
|
+
static readonly NO_MATCHING_AUTHENTICATOR_FOR_PARAMS_ALGO = "No available authenticator supported any of the specified pubKeyCredParams algorithms";
|
|
14
|
+
static readonly INVALID_USER_ID_LENGTH = "User ID has invalid length";
|
|
15
|
+
constructor({ message, cause, name }: {
|
|
16
|
+
message: string;
|
|
17
|
+
cause: Error;
|
|
18
|
+
name?: string;
|
|
19
|
+
});
|
|
20
|
+
static identifyAuthenticationError({ error, options, platform, }: {
|
|
21
|
+
error: Error;
|
|
22
|
+
options: CredentialRequestOptions;
|
|
23
|
+
platform: Platform;
|
|
24
|
+
}): FidoOptionsError | Error;
|
|
25
|
+
static identifyRegistrationError({ error, options, platform, }: {
|
|
26
|
+
error: Error;
|
|
27
|
+
options: CredentialCreationOptions;
|
|
28
|
+
platform: Platform;
|
|
29
|
+
}): FidoOptionsError | Error;
|
|
30
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FidoOptionsError = void 0;
|
|
4
|
+
class FidoOptionsError extends Error {
|
|
5
|
+
constructor({ message, cause, name }) {
|
|
6
|
+
super(message, { cause });
|
|
7
|
+
this.name = name !== null && name !== void 0 ? name : cause.name;
|
|
8
|
+
}
|
|
9
|
+
static identifyAuthenticationError({ error, options, platform, }) {
|
|
10
|
+
const { publicKey } = options;
|
|
11
|
+
if (!publicKey) {
|
|
12
|
+
return new FidoOptionsError({
|
|
13
|
+
message: FidoOptionsError.MISSING_PUBLIC_KEY_PROPERTY,
|
|
14
|
+
cause: new Error(FidoOptionsError.MISSING_PUBLIC_KEY_PROPERTY),
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
if (error.name === 'AbortError') {
|
|
18
|
+
if (options.signal instanceof AbortSignal) {
|
|
19
|
+
return new FidoOptionsError({
|
|
20
|
+
message: FidoOptionsError.ABORT_SIGNAL,
|
|
21
|
+
cause: error,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
else if (error.name === 'NotAllowedError') {
|
|
26
|
+
return new FidoOptionsError({
|
|
27
|
+
message: error.message,
|
|
28
|
+
cause: error,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
else if (error.name === 'SecurityError') {
|
|
32
|
+
const currentDomain = platform.getOrigin();
|
|
33
|
+
if (publicKey.rpId !== currentDomain) {
|
|
34
|
+
return new FidoOptionsError({
|
|
35
|
+
message: `${FidoOptionsError.INVALID_RP_ID}: ${publicKey.rpId}`,
|
|
36
|
+
cause: error,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
return new FidoOptionsError({
|
|
41
|
+
message: `${FidoOptionsError.SECURITY_ERROR_FOUND}: ${error.message}`,
|
|
42
|
+
cause: error,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else if (error.name === 'UnknownError') {
|
|
47
|
+
return new FidoOptionsError({
|
|
48
|
+
message: FidoOptionsError.UNKNOWN_ERROR,
|
|
49
|
+
cause: error,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
return error;
|
|
53
|
+
}
|
|
54
|
+
static identifyRegistrationError({ error, options, platform, }) {
|
|
55
|
+
var _a, _b, _c;
|
|
56
|
+
const { publicKey } = options;
|
|
57
|
+
if (!publicKey) {
|
|
58
|
+
return new FidoOptionsError({
|
|
59
|
+
message: FidoOptionsError.MISSING_PUBLIC_KEY_PROPERTY,
|
|
60
|
+
cause: new Error(FidoOptionsError.MISSING_PUBLIC_KEY_PROPERTY),
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
if (error.name === 'InvalidStateError') {
|
|
64
|
+
return new FidoOptionsError({
|
|
65
|
+
message: FidoOptionsError.INVALID_STATE_ERROR,
|
|
66
|
+
cause: error,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
else if (error.name === 'AbortError') {
|
|
70
|
+
if (options.signal instanceof AbortSignal) {
|
|
71
|
+
return new FidoOptionsError({
|
|
72
|
+
message: this.ABORT_SIGNAL,
|
|
73
|
+
cause: error,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
else if (error.name === 'ConstraintError') {
|
|
78
|
+
if (((_a = publicKey.authenticatorSelection) === null || _a === void 0 ? void 0 : _a.requireResidentKey) === true) {
|
|
79
|
+
return new FidoOptionsError({
|
|
80
|
+
message: this.CONSTRAINT_ERROR,
|
|
81
|
+
cause: error,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
else if (options.mediation === 'conditional' &&
|
|
85
|
+
((_b = publicKey.authenticatorSelection) === null || _b === void 0 ? void 0 : _b.userVerification) === 'required') {
|
|
86
|
+
return new FidoOptionsError({
|
|
87
|
+
message: this.USER_VERIFICATION_NOT_POSSILE,
|
|
88
|
+
cause: error,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
else if (((_c = publicKey.authenticatorSelection) === null || _c === void 0 ? void 0 : _c.userVerification) === 'required') {
|
|
92
|
+
return new FidoOptionsError({
|
|
93
|
+
message: this.NO_MATCHING_AUTHENTICATOR,
|
|
94
|
+
cause: error,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else if (error.name === 'NotAllowedError') {
|
|
99
|
+
return new FidoOptionsError({
|
|
100
|
+
message: error.message,
|
|
101
|
+
cause: error,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
else if (error.name === 'NotSupportedError') {
|
|
105
|
+
const validPubKeyCredParams = publicKey.pubKeyCredParams.filter((param) => param.type === 'public-key');
|
|
106
|
+
if (validPubKeyCredParams.length === 0) {
|
|
107
|
+
return new FidoOptionsError({
|
|
108
|
+
message: this.INVALID_CRED_PARAMS,
|
|
109
|
+
cause: error,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
return new FidoOptionsError({
|
|
113
|
+
message: FidoOptionsError.NO_MATCHING_AUTHENTICATOR_FOR_PARAMS_ALGO,
|
|
114
|
+
cause: error,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
else if (error.name === 'SecurityError') {
|
|
118
|
+
const currentDomain = platform.getOrigin();
|
|
119
|
+
if (publicKey.rp.id !== currentDomain) {
|
|
120
|
+
return new FidoOptionsError({
|
|
121
|
+
message: `${FidoOptionsError.INVALID_RP_ID}: ${publicKey.rp.id}`,
|
|
122
|
+
cause: error,
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
return new FidoOptionsError({
|
|
127
|
+
message: `${FidoOptionsError.SECURITY_ERROR_FOUND}: ${error.message}`,
|
|
128
|
+
cause: error,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else if (error.name === 'TypeError') {
|
|
133
|
+
if (publicKey.user.id.byteLength < 1 || publicKey.user.id.byteLength > 64) {
|
|
134
|
+
return new FidoOptionsError({
|
|
135
|
+
message: FidoOptionsError.INVALID_USER_ID_LENGTH,
|
|
136
|
+
cause: error,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
else if (error.name === 'UnknownError') {
|
|
141
|
+
return new FidoOptionsError({
|
|
142
|
+
message: FidoOptionsError.UNKNOWN_ERROR,
|
|
143
|
+
cause: error,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return error;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
FidoOptionsError.MISSING_PUBLIC_KEY_PROPERTY = 'options missing publicKey property';
|
|
150
|
+
FidoOptionsError.ABORT_SIGNAL = 'Authentication was sent an abort signal';
|
|
151
|
+
FidoOptionsError.INVALID_STATE_ERROR = 'The authenticator was already registered';
|
|
152
|
+
FidoOptionsError.UNKNOWN_ERROR = 'Unknown error: the authenticator was unable to process the predefined options, or unable to generate a new credential';
|
|
153
|
+
FidoOptionsError.SECURITY_ERROR_FOUND = 'Security error found';
|
|
154
|
+
FidoOptionsError.INVALID_RP_ID = 'The rp.id is not valid for the current domain';
|
|
155
|
+
FidoOptionsError.CONSTRAINT_ERROR = 'Discoverable credentials is required but found no matching supported authenticator';
|
|
156
|
+
FidoOptionsError.USER_VERIFICATION_NOT_POSSILE = 'User verification is required during automatic registration but this could not be performed';
|
|
157
|
+
FidoOptionsError.NO_MATCHING_AUTHENTICATOR = 'User verification is required but found no matching supported authenticator';
|
|
158
|
+
FidoOptionsError.INVALID_CRED_PARAMS = 'No entry in pubKeyCredParams having the type of public-key';
|
|
159
|
+
FidoOptionsError.NO_MATCHING_AUTHENTICATOR_FOR_PARAMS_ALGO = 'No available authenticator supported any of the specified pubKeyCredParams algorithms';
|
|
160
|
+
FidoOptionsError.INVALID_USER_ID_LENGTH = 'User ID has invalid length';
|
|
161
|
+
exports.FidoOptionsError = FidoOptionsError;
|
|
@@ -110,7 +110,7 @@ class MainAuthenticator {
|
|
|
110
110
|
})
|
|
111
111
|
.then((response) => {
|
|
112
112
|
if (response.error) {
|
|
113
|
-
reject(new auth_error_1.default(response.error.message, response.error.code, response.next));
|
|
113
|
+
reject(new auth_error_1.default(response.error.message, response.error.code, response.next, false));
|
|
114
114
|
}
|
|
115
115
|
else {
|
|
116
116
|
resolve();
|