@forgerock/davinci-client 1.1.0 → 1.3.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/dist/src/index.d.ts +2 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +2 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib/client.store.d.ts +47 -46
- package/dist/src/lib/client.store.d.ts.map +1 -1
- package/dist/src/lib/client.store.js +99 -86
- package/dist/src/lib/client.store.js.map +1 -1
- package/dist/src/lib/client.store.utils.d.ts +27 -14
- package/dist/src/lib/client.store.utils.d.ts.map +1 -1
- package/dist/src/lib/client.store.utils.js +15 -2
- package/dist/src/lib/client.store.utils.js.map +1 -1
- package/dist/src/lib/client.types.d.ts +58 -4
- package/dist/src/lib/client.types.d.ts.map +1 -1
- package/dist/src/lib/collector.types.d.ts +204 -11
- package/dist/src/lib/collector.types.d.ts.map +1 -1
- package/dist/src/lib/collector.types.js +0 -3
- package/dist/src/lib/collector.types.js.map +1 -1
- package/dist/src/lib/collector.utils.d.ts +75 -21
- package/dist/src/lib/collector.utils.d.ts.map +1 -1
- package/dist/src/lib/collector.utils.js +318 -16
- package/dist/src/lib/collector.utils.js.map +1 -1
- package/dist/src/lib/config.types.d.ts +3 -3
- package/dist/src/lib/config.types.d.ts.map +1 -1
- package/dist/src/lib/davinci.api.d.ts +6 -4
- package/dist/src/lib/davinci.api.d.ts.map +1 -1
- package/dist/src/lib/davinci.api.js +32 -18
- package/dist/src/lib/davinci.api.js.map +1 -1
- package/dist/src/lib/davinci.types.d.ts +96 -7
- package/dist/src/lib/davinci.types.d.ts.map +1 -1
- package/dist/src/lib/davinci.utils.d.ts +4 -7
- package/dist/src/lib/davinci.utils.d.ts.map +1 -1
- package/dist/src/lib/davinci.utils.js +16 -31
- package/dist/src/lib/davinci.utils.js.map +1 -1
- package/dist/src/lib/fido/fido.d.ts +27 -0
- package/dist/src/lib/fido/fido.d.ts.map +1 -0
- package/dist/src/lib/fido/fido.js +108 -0
- package/dist/src/lib/fido/fido.js.map +1 -0
- package/dist/src/lib/fido/fido.utils.d.ts +31 -0
- package/dist/src/lib/fido/fido.utils.d.ts.map +1 -0
- package/dist/src/lib/fido/fido.utils.js +115 -0
- package/dist/src/lib/fido/fido.utils.js.map +1 -0
- package/dist/src/lib/node.reducer.d.ts +4 -4
- package/dist/src/lib/node.reducer.d.ts.map +1 -1
- package/dist/src/lib/node.reducer.js +95 -8
- package/dist/src/lib/node.reducer.js.map +1 -1
- package/dist/src/lib/node.slice.d.ts +44 -8
- package/dist/src/lib/node.slice.d.ts.map +1 -1
- package/dist/src/lib/node.slice.js +40 -10
- package/dist/src/lib/node.slice.js.map +1 -1
- package/dist/src/lib/node.types.d.ts +6 -5
- package/dist/src/lib/node.types.d.ts.map +1 -1
- package/dist/src/lib/node.utils.d.ts +2 -2
- package/dist/src/lib/node.utils.d.ts.map +1 -1
- package/dist/src/lib/wellknown.api.d.ts +1 -1
- package/dist/src/types.d.ts +18 -4
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +1 -2
- package/dist/src/types.js.map +1 -1
- package/package.json +11 -20
- package/dist/src/lib/authorize.utils.d.ts +0 -22
- package/dist/src/lib/authorize.utils.d.ts.map +0 -1
- package/dist/src/lib/authorize.utils.js +0 -47
- package/dist/src/lib/authorize.utils.js.map +0 -1
- package/dist/src/lib/effects/request.effect.mock.d.ts +0 -4
- package/dist/src/lib/effects/request.effect.mock.d.ts.map +0 -1
- package/dist/src/lib/effects/request.effect.mock.js +0 -106
- package/dist/src/lib/effects/request.effect.mock.js.map +0 -1
- package/dist/src/lib/effects/request.effect.types.d.ts +0 -20
- package/dist/src/lib/effects/request.effect.types.d.ts.map +0 -1
- package/dist/src/lib/effects/request.effect.types.js +0 -2
- package/dist/src/lib/effects/request.effect.types.js.map +0 -1
- package/dist/src/lib/effects/request.effect.unions.d.ts +0 -12
- package/dist/src/lib/effects/request.effect.unions.d.ts.map +0 -1
- package/dist/src/lib/effects/request.effect.unions.js +0 -16
- package/dist/src/lib/effects/request.effect.unions.js.map +0 -1
- package/dist/src/lib/effects/request.effect.utils.d.ts +0 -27
- package/dist/src/lib/effects/request.effect.utils.d.ts.map +0 -1
- package/dist/src/lib/effects/request.effect.utils.js +0 -57
- package/dist/src/lib/effects/request.effect.utils.js.map +0 -1
- package/dist/src/lib/error.types.d.ts +0 -6
- package/dist/src/lib/error.types.d.ts.map +0 -1
- package/dist/src/lib/error.types.js +0 -2
- package/dist/src/lib/error.types.js.map +0 -1
|
@@ -4,15 +4,19 @@ import { nodeSlice } from './node.slice.js';
|
|
|
4
4
|
* @param {ContinueNode} node - The node to transform into a DaVinciRequest
|
|
5
5
|
* @returns {DaVinciRequest} - The transformed request object
|
|
6
6
|
*/
|
|
7
|
-
export function transformSubmitRequest(node) {
|
|
7
|
+
export function transformSubmitRequest(node, logger) {
|
|
8
8
|
// Filter out ActionCollectors as they are not used in form submissions
|
|
9
9
|
const collectors = node.client?.collectors?.filter((collector) => collector.category === 'MultiValueCollector' ||
|
|
10
10
|
collector.category === 'SingleValueCollector' ||
|
|
11
|
-
collector.category === 'ValidatedSingleValueCollector'
|
|
11
|
+
collector.category === 'ValidatedSingleValueCollector' ||
|
|
12
|
+
collector.category === 'ObjectValueCollector' ||
|
|
13
|
+
collector.category === 'SingleValueAutoCollector' ||
|
|
14
|
+
collector.category === 'ObjectValueAutoCollector');
|
|
12
15
|
const formData = collectors?.reduce((acc, collector) => {
|
|
13
16
|
acc[collector.input.key] = collector.input.value;
|
|
14
17
|
return acc;
|
|
15
18
|
}, {});
|
|
19
|
+
logger.debug('Transforming submit request', { node, formData });
|
|
16
20
|
return {
|
|
17
21
|
id: node.server.id || '',
|
|
18
22
|
eventName: node.server.eventName || '',
|
|
@@ -32,7 +36,8 @@ export function transformSubmitRequest(node) {
|
|
|
32
36
|
* @param {string} action - The action to transform into a DaVinciRequest
|
|
33
37
|
* @returns {DaVinciRequest} - The transformed request object
|
|
34
38
|
*/
|
|
35
|
-
export function transformActionRequest(node, action) {
|
|
39
|
+
export function transformActionRequest(node, action, logger) {
|
|
40
|
+
logger.debug('Transforming action request', { node, action });
|
|
36
41
|
return {
|
|
37
42
|
id: node.server.id || '',
|
|
38
43
|
eventName: node.server.eventName || '',
|
|
@@ -45,11 +50,12 @@ export function transformActionRequest(node, action) {
|
|
|
45
50
|
},
|
|
46
51
|
};
|
|
47
52
|
}
|
|
48
|
-
export function handleResponse(cacheEntry, dispatch, status) {
|
|
53
|
+
export function handleResponse(cacheEntry, dispatch, status, logger) {
|
|
49
54
|
/**
|
|
50
55
|
* 5XX errors are treated as unrecoverable failures
|
|
51
56
|
*/
|
|
52
57
|
if (cacheEntry.isError && cacheEntry.error.status >= 500) {
|
|
58
|
+
logger.error('Response of 5XX indicates unrecoverable failure');
|
|
53
59
|
const data = cacheEntry.error.data;
|
|
54
60
|
const requestId = cacheEntry.requestId;
|
|
55
61
|
dispatch(nodeSlice.actions.failure({ data, requestId, httpStatus: cacheEntry.error.status }));
|
|
@@ -63,6 +69,7 @@ export function handleResponse(cacheEntry, dispatch, status) {
|
|
|
63
69
|
const requestId = cacheEntry.requestId;
|
|
64
70
|
// Filter out client-side "timeout" related unrecoverable failures
|
|
65
71
|
if (data.code === 1999 || data.code === 'requestTimedOut') {
|
|
72
|
+
logger.error('Error is a client-side timeout');
|
|
66
73
|
dispatch(nodeSlice.actions.failure({ data, requestId, httpStatus: cacheEntry.error.status }));
|
|
67
74
|
return; // Filter out timeouts
|
|
68
75
|
}
|
|
@@ -70,9 +77,11 @@ export function handleResponse(cacheEntry, dispatch, status) {
|
|
|
70
77
|
if (data.connectorId === 'pingOneAuthenticationConnector' &&
|
|
71
78
|
(data.capabilityName === 'returnSuccessResponseRedirect' ||
|
|
72
79
|
data.capabilityName === 'setSession')) {
|
|
80
|
+
logger.error('Error is a PingOne Authentication Connector unrecoverable failure');
|
|
73
81
|
dispatch(nodeSlice.actions.failure({ data, requestId, httpStatus: cacheEntry.error.status }));
|
|
74
82
|
return;
|
|
75
83
|
}
|
|
84
|
+
logger.debug('Response with this error type should be recoverable');
|
|
76
85
|
// If we're still here, we have a 4XX failure that should be recoverable
|
|
77
86
|
dispatch(nodeSlice.actions.error({ data, requestId, httpStatus: cacheEntry.error.status }));
|
|
78
87
|
return;
|
|
@@ -81,6 +90,7 @@ export function handleResponse(cacheEntry, dispatch, status) {
|
|
|
81
90
|
* Check for 3XX errors that result in CORS errors, reported as FETCH_ERROR
|
|
82
91
|
*/
|
|
83
92
|
if (cacheEntry.isError && cacheEntry.error.status === 'FETCH_ERROR') {
|
|
93
|
+
logger.error('Response with FETCH_ERROR indicates configuration failure. Please ensure a correct Client ID for your OAuth application.');
|
|
84
94
|
const data = {
|
|
85
95
|
code: cacheEntry.error.status,
|
|
86
96
|
message: 'Fetch Error: Please ensure a correct Client ID for your OAuth application.',
|
|
@@ -94,6 +104,7 @@ export function handleResponse(cacheEntry, dispatch, status) {
|
|
|
94
104
|
* we need to handle this as a failure or return as unknown.
|
|
95
105
|
*/
|
|
96
106
|
if (cacheEntry.isSuccess && 'error' in cacheEntry.data) {
|
|
107
|
+
logger.error('Response with `isSuccess` but `error` property indicates unrecoverable failure');
|
|
97
108
|
const data = cacheEntry.data;
|
|
98
109
|
const requestId = cacheEntry.requestId;
|
|
99
110
|
dispatch(nodeSlice.actions.failure({
|
|
@@ -110,6 +121,7 @@ export function handleResponse(cacheEntry, dispatch, status) {
|
|
|
110
121
|
if (cacheEntry.isSuccess && 'status' in cacheEntry.data) {
|
|
111
122
|
const status = cacheEntry.data.status.toLowerCase();
|
|
112
123
|
if (status === 'failure') {
|
|
124
|
+
logger.error('Response with `isSuccess` and `status` of "failure" indicates unrecoverable failure');
|
|
113
125
|
const data = cacheEntry.data;
|
|
114
126
|
const requestId = cacheEntry.requestId;
|
|
115
127
|
dispatch(nodeSlice.actions.failure({
|
|
@@ -155,31 +167,4 @@ export function handleResponse(cacheEntry, dispatch, status) {
|
|
|
155
167
|
}
|
|
156
168
|
}
|
|
157
169
|
}
|
|
158
|
-
export function authorize(serverSlice, collector) {
|
|
159
|
-
if (serverSlice && '_links' in serverSlice) {
|
|
160
|
-
const continueUrl = serverSlice._links?.['continue']?.href ?? null;
|
|
161
|
-
if (continueUrl) {
|
|
162
|
-
window.localStorage.setItem('continueUrl', continueUrl);
|
|
163
|
-
if (collector.output.url) {
|
|
164
|
-
window.location.assign(collector.output.url);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
return {
|
|
169
|
-
error: {
|
|
170
|
-
message: 'No url found in collector, social login needs a url in the collector to navigate to',
|
|
171
|
-
type: 'network_error',
|
|
172
|
-
},
|
|
173
|
-
type: 'internal_error',
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
return {
|
|
177
|
-
error: {
|
|
178
|
-
message: 'No Continue Url found, social login needs a continue url to be saved in localStorage',
|
|
179
|
-
type: 'network_error',
|
|
180
|
-
},
|
|
181
|
-
type: 'internal_error',
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
170
|
//# sourceMappingURL=davinci.utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"davinci.utils.js","sourceRoot":"","sources":["../../../src/lib/davinci.utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"davinci.utils.js","sourceRoot":"","sources":["../../../src/lib/davinci.utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { GenericError } from '@forgerock/sdk-types';
|
|
2
|
+
import type { FidoAuthenticationInputValue, FidoRegistrationInputValue } from '../collector.types.js';
|
|
3
|
+
import type { FidoAuthenticationOptions, FidoRegistrationOptions } from '../davinci.types.js';
|
|
4
|
+
export interface FidoClient {
|
|
5
|
+
/**
|
|
6
|
+
* Create a keypair and get the public key credential to send back to DaVinci for registration
|
|
7
|
+
* @function register
|
|
8
|
+
* @param { FidoRegistrationOptions } options - DaVinci FIDO registration options
|
|
9
|
+
* @returns { Promise<FidoRegistrationInputValue | GenericError> } - The formatted credential for DaVinci or an error
|
|
10
|
+
*/
|
|
11
|
+
register: (options: FidoRegistrationOptions) => Promise<FidoRegistrationInputValue | GenericError>;
|
|
12
|
+
/**
|
|
13
|
+
* Get an assertion to send back to DaVinci for authentication
|
|
14
|
+
* @function authenticate
|
|
15
|
+
* @param { FidoAuthenticationOptions } options - DaVinci FIDO authentication options
|
|
16
|
+
* @returns { Promise<FidoAuthenticationInputValue | GenericError> } - The formatted assertion for DaVinci or an error
|
|
17
|
+
*/
|
|
18
|
+
authenticate: (options: FidoAuthenticationOptions) => Promise<FidoAuthenticationInputValue | GenericError>;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A client function that returns a set of methods for transforming DaVinci data and
|
|
22
|
+
* interacting with the WebAuthn API for registration and authentication
|
|
23
|
+
* @function fido
|
|
24
|
+
* @returns {FidoClient} - A set of methods for FIDO registration and authentication
|
|
25
|
+
*/
|
|
26
|
+
export declare function fido(): FidoClient;
|
|
27
|
+
//# sourceMappingURL=fido.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fido.d.ts","sourceRoot":"","sources":["../../../../src/lib/fido/fido.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EACV,4BAA4B,EAC5B,0BAA0B,EAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAE9F,MAAM,WAAW,UAAU;IACzB;;;;;OAKG;IACH,QAAQ,EAAE,CACR,OAAO,EAAE,uBAAuB,KAC7B,OAAO,CAAC,0BAA0B,GAAG,YAAY,CAAC,CAAC;IACxD;;;;;OAKG;IACH,YAAY,EAAE,CACZ,OAAO,EAAE,yBAAyB,KAC/B,OAAO,CAAC,4BAA4B,GAAG,YAAY,CAAC,CAAC;CAC3D;AAED;;;;;GAKG;AACH,wBAAgB,IAAI,IAAI,UAAU,CA2GjC"}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 Ping Identity Corporation. All rights reserved.
|
|
3
|
+
*
|
|
4
|
+
* This software may be modified and distributed under the terms
|
|
5
|
+
* of the MIT license. See the LICENSE file for details.
|
|
6
|
+
*/
|
|
7
|
+
import { Micro } from 'effect';
|
|
8
|
+
import { exitIsFail, exitIsSuccess } from 'effect/Micro';
|
|
9
|
+
import { transformAssertion, transformAuthenticationOptions, transformPublicKeyCredential, transformRegistrationOptions, } from './fido.utils.js';
|
|
10
|
+
/**
|
|
11
|
+
* A client function that returns a set of methods for transforming DaVinci data and
|
|
12
|
+
* interacting with the WebAuthn API for registration and authentication
|
|
13
|
+
* @function fido
|
|
14
|
+
* @returns {FidoClient} - A set of methods for FIDO registration and authentication
|
|
15
|
+
*/
|
|
16
|
+
export function fido() {
|
|
17
|
+
return {
|
|
18
|
+
/**
|
|
19
|
+
* Call WebAuthn API to create keypair and get public key credential
|
|
20
|
+
*/
|
|
21
|
+
register: async function register(options) {
|
|
22
|
+
const createCredentialµ = Micro.sync(() => transformRegistrationOptions(options)).pipe(Micro.flatMap((publicKeyCredentialCreationOptions) => Micro.tryPromise({
|
|
23
|
+
try: () => navigator.credentials.create({
|
|
24
|
+
publicKey: publicKeyCredentialCreationOptions,
|
|
25
|
+
}),
|
|
26
|
+
catch: (error) => {
|
|
27
|
+
console.error('Failed to create keypair: ', error);
|
|
28
|
+
return {
|
|
29
|
+
error: 'registration_error',
|
|
30
|
+
message: 'FIDO registration failed',
|
|
31
|
+
type: 'fido_error',
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
})), Micro.flatMap((credential) => {
|
|
35
|
+
if (!credential) {
|
|
36
|
+
return Micro.fail({
|
|
37
|
+
error: 'registration_error',
|
|
38
|
+
message: 'FIDO registration failed: No credential returned',
|
|
39
|
+
type: 'fido_error',
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
const formattedCredential = transformPublicKeyCredential(credential);
|
|
44
|
+
return Micro.succeed(formattedCredential);
|
|
45
|
+
}
|
|
46
|
+
}));
|
|
47
|
+
const result = await Micro.runPromiseExit(createCredentialµ);
|
|
48
|
+
if (exitIsSuccess(result)) {
|
|
49
|
+
return result.value;
|
|
50
|
+
}
|
|
51
|
+
else if (exitIsFail(result)) {
|
|
52
|
+
return result.cause.error;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
return {
|
|
56
|
+
error: 'fido_registration_error',
|
|
57
|
+
message: result.cause.message,
|
|
58
|
+
type: 'unknown_error',
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
/**
|
|
63
|
+
* Call WebAuthn API to get assertion
|
|
64
|
+
*/
|
|
65
|
+
authenticate: async function authenticate(options) {
|
|
66
|
+
const getAssertionµ = Micro.sync(() => transformAuthenticationOptions(options)).pipe(Micro.flatMap((publicKeyCredentialRequestOptions) => Micro.tryPromise({
|
|
67
|
+
try: () => navigator.credentials.get({
|
|
68
|
+
publicKey: publicKeyCredentialRequestOptions,
|
|
69
|
+
}),
|
|
70
|
+
catch: (error) => {
|
|
71
|
+
console.error('Failed to authenticate: ', error);
|
|
72
|
+
return {
|
|
73
|
+
error: 'authentication_error',
|
|
74
|
+
message: 'FIDO authentication failed',
|
|
75
|
+
type: 'fido_error',
|
|
76
|
+
};
|
|
77
|
+
},
|
|
78
|
+
})), Micro.flatMap((assertion) => {
|
|
79
|
+
if (!assertion) {
|
|
80
|
+
return Micro.fail({
|
|
81
|
+
error: 'authentication_error',
|
|
82
|
+
message: 'FIDO authentication failed: No credential returned',
|
|
83
|
+
type: 'fido_error',
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
const formattedAssertion = transformAssertion(assertion);
|
|
88
|
+
return Micro.succeed(formattedAssertion);
|
|
89
|
+
}
|
|
90
|
+
}));
|
|
91
|
+
const result = await Micro.runPromiseExit(getAssertionµ);
|
|
92
|
+
if (exitIsSuccess(result)) {
|
|
93
|
+
return result.value;
|
|
94
|
+
}
|
|
95
|
+
else if (exitIsFail(result)) {
|
|
96
|
+
return result.cause.error;
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
return {
|
|
100
|
+
error: 'fido_authentication_error',
|
|
101
|
+
message: result.cause.message,
|
|
102
|
+
type: 'unknown_error',
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=fido.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fido.js","sourceRoot":"","sources":["../../../../src/lib/fido/fido.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { FidoAuthenticationInputValue, FidoRegistrationInputValue } from '../collector.types.js';
|
|
2
|
+
import type { FidoAuthenticationOptions, FidoRegistrationOptions } from '../davinci.types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Convert DaVinci registration options to PublicKeyCredentialCreationOptions
|
|
5
|
+
* @function transformRegistrationOptions
|
|
6
|
+
* @param { FidoRegistrationOptions } options - DaVinci FIDO registration options
|
|
7
|
+
* @returns { PublicKeyCredentialCreationOptions } - WebAuthn API compatible registration options
|
|
8
|
+
*/
|
|
9
|
+
export declare function transformRegistrationOptions(options: FidoRegistrationOptions): PublicKeyCredentialCreationOptions;
|
|
10
|
+
/**
|
|
11
|
+
* Format the credential to send back to DaVinci for registration
|
|
12
|
+
* @function transformPublicKeyCredential
|
|
13
|
+
* @param { PublicKeyCredential } credential - The credential returned from navigator.credentials.create()
|
|
14
|
+
* @returns { FidoRegistrationInputValue } - The formatted credential for registering with DaVinci
|
|
15
|
+
*/
|
|
16
|
+
export declare function transformPublicKeyCredential(credential: PublicKeyCredential): FidoRegistrationInputValue;
|
|
17
|
+
/**
|
|
18
|
+
* Convert DaVinci authentication options to PublicKeyCredentialRequestOptions
|
|
19
|
+
* @function transformAuthenticationOptions
|
|
20
|
+
* @param { FidoAuthenticationOptions } options - DaVinci FIDO authentication options
|
|
21
|
+
* @returns { PublicKeyCredentialRequestOptions } - WebAuthn API compatible authentication options
|
|
22
|
+
*/
|
|
23
|
+
export declare function transformAuthenticationOptions(options: FidoAuthenticationOptions): PublicKeyCredentialRequestOptions;
|
|
24
|
+
/**
|
|
25
|
+
* Format the assertion to send back to DaVinci for authentication
|
|
26
|
+
* @function transformAssertion
|
|
27
|
+
* @param { PublicKeyCredential } credential - The credential returned from navigator.credentials.get()
|
|
28
|
+
* @returns { FidoAuthenticationInputValue } - The formatted credential for authenticating with DaVinci
|
|
29
|
+
*/
|
|
30
|
+
export declare function transformAssertion(credential: PublicKeyCredential): FidoAuthenticationInputValue;
|
|
31
|
+
//# sourceMappingURL=fido.utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fido.utils.d.ts","sourceRoot":"","sources":["../../../../src/lib/fido/fido.utils.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,4BAA4B,EAC5B,0BAA0B,EAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAe9F;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,uBAAuB,GAC/B,kCAAkC,CAqBpC;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,UAAU,EAAE,mBAAmB,GAC9B,0BAA0B,CAoB5B;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,yBAAyB,GACjC,iCAAiC,CAanC;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,mBAAmB,GAAG,4BAA4B,CAyBhG"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
function convertArrayToBuffer(arr) {
|
|
2
|
+
return new Int8Array(arr).buffer;
|
|
3
|
+
}
|
|
4
|
+
function convertBufferToBase64(buffer) {
|
|
5
|
+
const byteArray = new Uint8Array(buffer);
|
|
6
|
+
let binaryString = '';
|
|
7
|
+
for (let i = 0; i < byteArray.byteLength; i++) {
|
|
8
|
+
binaryString += String.fromCharCode(byteArray[i]);
|
|
9
|
+
}
|
|
10
|
+
return btoa(binaryString);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Convert DaVinci registration options to PublicKeyCredentialCreationOptions
|
|
14
|
+
* @function transformRegistrationOptions
|
|
15
|
+
* @param { FidoRegistrationOptions } options - DaVinci FIDO registration options
|
|
16
|
+
* @returns { PublicKeyCredentialCreationOptions } - WebAuthn API compatible registration options
|
|
17
|
+
*/
|
|
18
|
+
export function transformRegistrationOptions(options) {
|
|
19
|
+
const pubKeyCredParams = options.pubKeyCredParams.map((param) => ({
|
|
20
|
+
type: param.type,
|
|
21
|
+
alg: typeof param.alg === 'string' ? parseInt(param.alg, 10) : param.alg,
|
|
22
|
+
}));
|
|
23
|
+
const excludeCredentials = options.excludeCredentials?.map((param) => ({
|
|
24
|
+
type: param.type,
|
|
25
|
+
id: convertArrayToBuffer(param.id),
|
|
26
|
+
transports: param.transports,
|
|
27
|
+
}));
|
|
28
|
+
return {
|
|
29
|
+
...options,
|
|
30
|
+
challenge: convertArrayToBuffer(options.challenge),
|
|
31
|
+
user: {
|
|
32
|
+
...options.user,
|
|
33
|
+
id: convertArrayToBuffer(options.user.id),
|
|
34
|
+
},
|
|
35
|
+
pubKeyCredParams,
|
|
36
|
+
excludeCredentials,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Format the credential to send back to DaVinci for registration
|
|
41
|
+
* @function transformPublicKeyCredential
|
|
42
|
+
* @param { PublicKeyCredential } credential - The credential returned from navigator.credentials.create()
|
|
43
|
+
* @returns { FidoRegistrationInputValue } - The formatted credential for registering with DaVinci
|
|
44
|
+
*/
|
|
45
|
+
export function transformPublicKeyCredential(credential) {
|
|
46
|
+
const credentialResponse = credential.response;
|
|
47
|
+
const clientDataJSON = convertBufferToBase64(credentialResponse.clientDataJSON);
|
|
48
|
+
const attestationObject = convertBufferToBase64(credentialResponse.attestationObject);
|
|
49
|
+
const rawId = convertBufferToBase64(credential.rawId);
|
|
50
|
+
return {
|
|
51
|
+
attestationValue: {
|
|
52
|
+
...credential,
|
|
53
|
+
id: credential.id,
|
|
54
|
+
rawId,
|
|
55
|
+
type: credential.type,
|
|
56
|
+
authenticatorAttachment: credential.authenticatorAttachment,
|
|
57
|
+
response: {
|
|
58
|
+
...credentialResponse,
|
|
59
|
+
clientDataJSON,
|
|
60
|
+
attestationObject,
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Convert DaVinci authentication options to PublicKeyCredentialRequestOptions
|
|
67
|
+
* @function transformAuthenticationOptions
|
|
68
|
+
* @param { FidoAuthenticationOptions } options - DaVinci FIDO authentication options
|
|
69
|
+
* @returns { PublicKeyCredentialRequestOptions } - WebAuthn API compatible authentication options
|
|
70
|
+
*/
|
|
71
|
+
export function transformAuthenticationOptions(options) {
|
|
72
|
+
const allowCredentials = options.allowCredentials?.map((param) => ({
|
|
73
|
+
id: convertArrayToBuffer(param.id),
|
|
74
|
+
type: param.type,
|
|
75
|
+
transports: param.transports,
|
|
76
|
+
}));
|
|
77
|
+
const challenge = convertArrayToBuffer(options.challenge);
|
|
78
|
+
return {
|
|
79
|
+
...options,
|
|
80
|
+
challenge,
|
|
81
|
+
allowCredentials,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Format the assertion to send back to DaVinci for authentication
|
|
86
|
+
* @function transformAssertion
|
|
87
|
+
* @param { PublicKeyCredential } credential - The credential returned from navigator.credentials.get()
|
|
88
|
+
* @returns { FidoAuthenticationInputValue } - The formatted credential for authenticating with DaVinci
|
|
89
|
+
*/
|
|
90
|
+
export function transformAssertion(credential) {
|
|
91
|
+
const credentialResponse = credential.response;
|
|
92
|
+
const clientDataJSON = convertBufferToBase64(credentialResponse.clientDataJSON);
|
|
93
|
+
const authenticatorData = convertBufferToBase64(credentialResponse.authenticatorData);
|
|
94
|
+
const signature = convertBufferToBase64(credentialResponse.signature);
|
|
95
|
+
const userHandle = credentialResponse.userHandle
|
|
96
|
+
? convertBufferToBase64(credentialResponse.userHandle)
|
|
97
|
+
: null;
|
|
98
|
+
const rawId = convertBufferToBase64(credential.rawId);
|
|
99
|
+
return {
|
|
100
|
+
assertionValue: {
|
|
101
|
+
...credential,
|
|
102
|
+
id: credential.id,
|
|
103
|
+
rawId,
|
|
104
|
+
type: credential.type,
|
|
105
|
+
response: {
|
|
106
|
+
...credentialResponse,
|
|
107
|
+
clientDataJSON,
|
|
108
|
+
authenticatorData,
|
|
109
|
+
signature,
|
|
110
|
+
userHandle,
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=fido.utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fido.utils.js","sourceRoot":"","sources":["../../../../src/lib/fido/fido.utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { DaVinciField } from './davinci.types.js';
|
|
2
|
-
import { ActionCollector, MultiSelectCollector, SingleSelectCollector, FlowCollector, PasswordCollector, SingleValueCollector, IdpCollector, SubmitCollector, TextCollector, ReadOnlyCollector, ValidatedTextCollector } from './collector.types.js';
|
|
2
|
+
import type { ActionCollector, MultiSelectCollector, SingleSelectCollector, FlowCollector, PasswordCollector, SingleValueCollector, IdpCollector, SubmitCollector, TextCollector, ReadOnlyCollector, ValidatedTextCollector, DeviceAuthenticationCollector, DeviceRegistrationCollector, PhoneNumberCollector, PhoneNumberInputValue, UnknownCollector, ProtectCollector, FidoRegistrationCollector, FidoAuthenticationCollector, FidoAuthenticationInputValue, FidoRegistrationInputValue } from './collector.types.js';
|
|
3
3
|
/**
|
|
4
4
|
* @const nextCollectorValues - Action for setting the next collector values
|
|
5
5
|
* @see https://redux-toolkit.js.org/api/createAction
|
|
@@ -14,14 +14,14 @@ export declare const nextCollectorValues: import("@reduxjs/toolkit").ActionCreat
|
|
|
14
14
|
}, string>;
|
|
15
15
|
export declare const updateCollectorValues: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
|
|
16
16
|
id: string;
|
|
17
|
-
value: string | string[];
|
|
17
|
+
value: string | string[] | PhoneNumberInputValue | FidoRegistrationInputValue | FidoAuthenticationInputValue;
|
|
18
18
|
index?: number;
|
|
19
19
|
}, string>;
|
|
20
20
|
/**
|
|
21
21
|
* @const nodeCollectorReducer - Reducer for handling the collector values
|
|
22
22
|
* @see https://redux-toolkit.js.org/api/createReducer
|
|
23
23
|
*/
|
|
24
|
-
export declare const nodeCollectorReducer: import("@reduxjs/toolkit").Reducer<(TextCollector | SingleSelectCollector |
|
|
25
|
-
getInitialState: () => (TextCollector | SingleSelectCollector |
|
|
24
|
+
export declare const nodeCollectorReducer: import("@reduxjs/toolkit").Reducer<(TextCollector | SingleSelectCollector | ValidatedTextCollector | PasswordCollector | MultiSelectCollector | DeviceAuthenticationCollector | DeviceRegistrationCollector | PhoneNumberCollector | IdpCollector | SubmitCollector | FlowCollector | ReadOnlyCollector | UnknownCollector | ProtectCollector | FidoRegistrationCollector | FidoAuthenticationCollector | ActionCollector<"ActionCollector"> | SingleValueCollector<"SingleValueCollector">)[]> & {
|
|
25
|
+
getInitialState: () => (TextCollector | SingleSelectCollector | ValidatedTextCollector | PasswordCollector | MultiSelectCollector | DeviceAuthenticationCollector | DeviceRegistrationCollector | PhoneNumberCollector | IdpCollector | SubmitCollector | FlowCollector | ReadOnlyCollector | UnknownCollector | ProtectCollector | FidoRegistrationCollector | FidoAuthenticationCollector | ActionCollector<"ActionCollector"> | SingleValueCollector<"SingleValueCollector">)[];
|
|
26
26
|
};
|
|
27
27
|
//# sourceMappingURL=node.reducer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"node.reducer.d.ts","sourceRoot":"","sources":["../../../src/lib/node.reducer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"node.reducer.d.ts","sourceRoot":"","sources":["../../../src/lib/node.reducer.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,oBAAoB,CAAC;AACrE,OAAO,KAAK,EACV,eAAe,EACf,oBAAoB,EACpB,qBAAqB,EACrB,aAAa,EACb,iBAAiB,EACjB,oBAAoB,EACpB,YAAY,EACZ,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,sBAAsB,EACtB,6BAA6B,EAC7B,2BAA2B,EAC3B,oBAAoB,EACpB,qBAAqB,EAErB,gBAAgB,EAChB,gBAAgB,EAChB,yBAAyB,EACzB,2BAA2B,EAC3B,4BAA4B,EAC5B,0BAA0B,EAC3B,MAAM,sBAAsB,CAAC;AAE9B;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB;YACtB,YAAY,EAAE;cACZ;QAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE;UAC/B,CAAC;AAChB,eAAO,MAAM,qBAAqB;QAC5B,MAAM;WAEN,MAAM,GACN,MAAM,EAAE,GACR,qBAAqB,GACrB,0BAA0B,GAC1B,4BAA4B;YACxB,MAAM;UACC,CAAC;AA0BlB;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;CA2N/B,CAAC"}
|
|
@@ -11,7 +11,7 @@ import { createAction, createReducer } from '@reduxjs/toolkit';
|
|
|
11
11
|
/**
|
|
12
12
|
* Import the collector utilities
|
|
13
13
|
*/
|
|
14
|
-
import { returnActionCollector, returnFlowCollector, returnPasswordCollector,
|
|
14
|
+
import { returnActionCollector, returnFlowCollector, returnPasswordCollector, returnIdpCollector, returnSubmitCollector, returnTextCollector, returnSingleSelectCollector, returnMultiSelectCollector, returnReadOnlyCollector, returnObjectSelectCollector, returnObjectValueCollector, returnProtectCollector, returnUnknownCollector, returnFidoRegistrationCollector, returnFidoAuthenticationCollector, } from './collector.utils.js';
|
|
15
15
|
/**
|
|
16
16
|
* @const nextCollectorValues - Action for setting the next collector values
|
|
17
17
|
* @see https://redux-toolkit.js.org/api/createAction
|
|
@@ -71,11 +71,20 @@ export const nodeCollectorReducer = createReducer(initialCollectorValues, (build
|
|
|
71
71
|
// No data to send
|
|
72
72
|
return returnFlowCollector(field, idx);
|
|
73
73
|
}
|
|
74
|
+
case 'DEVICE_AUTHENTICATION':
|
|
75
|
+
case 'DEVICE_REGISTRATION': {
|
|
76
|
+
// Intentional fall-through
|
|
77
|
+
return returnObjectSelectCollector(field, idx);
|
|
78
|
+
}
|
|
74
79
|
case 'PASSWORD':
|
|
75
80
|
case 'PASSWORD_VERIFY': {
|
|
76
81
|
// No data to send
|
|
77
82
|
return returnPasswordCollector(field, idx);
|
|
78
83
|
}
|
|
84
|
+
case 'PHONE_NUMBER': {
|
|
85
|
+
const prefillData = data;
|
|
86
|
+
return returnObjectValueCollector(field, idx, prefillData);
|
|
87
|
+
}
|
|
79
88
|
case 'TEXT': {
|
|
80
89
|
const str = data;
|
|
81
90
|
return returnTextCollector(field, idx, str);
|
|
@@ -88,6 +97,18 @@ export const nodeCollectorReducer = createReducer(initialCollectorValues, (build
|
|
|
88
97
|
// No data to send
|
|
89
98
|
return returnSubmitCollector(field, idx);
|
|
90
99
|
}
|
|
100
|
+
case 'PROTECT': {
|
|
101
|
+
return returnProtectCollector(field, idx);
|
|
102
|
+
}
|
|
103
|
+
case 'FIDO2': {
|
|
104
|
+
if (field.action === 'REGISTER') {
|
|
105
|
+
return returnFidoRegistrationCollector(field, idx);
|
|
106
|
+
}
|
|
107
|
+
else if (field.action === 'AUTHENTICATE') {
|
|
108
|
+
return returnFidoAuthenticationCollector(field, idx);
|
|
109
|
+
}
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
91
112
|
default:
|
|
92
113
|
// Default is handled below
|
|
93
114
|
}
|
|
@@ -96,16 +117,15 @@ export const nodeCollectorReducer = createReducer(initialCollectorValues, (build
|
|
|
96
117
|
// No data to send
|
|
97
118
|
return returnActionCollector(field, idx, 'ActionCollector');
|
|
98
119
|
}
|
|
99
|
-
|
|
100
|
-
return returnSingleValueCollector(field, idx, 'SingleValueCollector', str);
|
|
120
|
+
return returnUnknownCollector(field, idx);
|
|
101
121
|
})
|
|
102
122
|
: [];
|
|
103
123
|
return collectors || [];
|
|
104
124
|
})
|
|
105
125
|
/**
|
|
106
126
|
* Using the `updateCollectorValues` const (e.g. `'node/update'`) to add the case
|
|
107
|
-
* 'node/
|
|
108
|
-
* transformed to `'node/
|
|
127
|
+
* 'node/update' is essentially derived `createSlice` below. `node.update()` is
|
|
128
|
+
* transformed to `'node/update'` for the action type.
|
|
109
129
|
*/
|
|
110
130
|
.addCase(updateCollectorValues, (state, action) => {
|
|
111
131
|
const collector = state.find((collector) => collector.id === action.payload.id);
|
|
@@ -122,14 +142,18 @@ export const nodeCollectorReducer = createReducer(initialCollectorValues, (build
|
|
|
122
142
|
throw new Error('Value argument cannot be undefined');
|
|
123
143
|
}
|
|
124
144
|
if (collector.category === 'SingleValueCollector' ||
|
|
125
|
-
collector.category === 'ValidatedSingleValueCollector'
|
|
126
|
-
|
|
127
|
-
|
|
145
|
+
collector.category === 'ValidatedSingleValueCollector' ||
|
|
146
|
+
collector.type === 'ProtectCollector') {
|
|
147
|
+
if (typeof action.payload.value !== 'string') {
|
|
148
|
+
throw new Error('Value argument must be a string');
|
|
128
149
|
}
|
|
129
150
|
collector.input.value = action.payload.value;
|
|
130
151
|
return;
|
|
131
152
|
}
|
|
132
153
|
if (collector.category === 'MultiValueCollector') {
|
|
154
|
+
if (typeof action.payload.value !== 'string' && !Array.isArray(action.payload.value)) {
|
|
155
|
+
throw new Error('MultiValueCollector does not accept an object');
|
|
156
|
+
}
|
|
133
157
|
if (Array.isArray(action.payload.value)) {
|
|
134
158
|
collector.input.value = [...action.payload.value];
|
|
135
159
|
}
|
|
@@ -138,6 +162,69 @@ export const nodeCollectorReducer = createReducer(initialCollectorValues, (build
|
|
|
138
162
|
}
|
|
139
163
|
return;
|
|
140
164
|
}
|
|
165
|
+
if (collector.type === 'DeviceAuthenticationCollector') {
|
|
166
|
+
if (typeof action.payload.id !== 'string') {
|
|
167
|
+
throw new Error('Index argument must be a string');
|
|
168
|
+
}
|
|
169
|
+
// Iterate through the options object and find option to update
|
|
170
|
+
const option = collector.output.options.find((option) => option.value === action.payload.value);
|
|
171
|
+
if (!option) {
|
|
172
|
+
throw new Error('No option found matching value to update');
|
|
173
|
+
}
|
|
174
|
+
// Remap values back to DaVinci spec
|
|
175
|
+
collector.input.value = {
|
|
176
|
+
type: option.type,
|
|
177
|
+
id: option.value,
|
|
178
|
+
value: option.content,
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
if (collector.type === 'DeviceRegistrationCollector') {
|
|
182
|
+
if (typeof action.payload.id !== 'string') {
|
|
183
|
+
throw new Error('Index argument must be a string');
|
|
184
|
+
}
|
|
185
|
+
// Iterate through the options object and find option to update
|
|
186
|
+
const option = collector.output.options.find((option) => option.value === action.payload.value);
|
|
187
|
+
if (!option) {
|
|
188
|
+
throw new Error('No option found matching value to update');
|
|
189
|
+
}
|
|
190
|
+
collector.input.value = option.type;
|
|
191
|
+
}
|
|
192
|
+
if (collector.type === 'PhoneNumberCollector') {
|
|
193
|
+
if (typeof action.payload.id !== 'string') {
|
|
194
|
+
throw new Error('Index argument must be a string');
|
|
195
|
+
}
|
|
196
|
+
if (typeof action.payload.value !== 'object') {
|
|
197
|
+
throw new Error('Value argument must be an object');
|
|
198
|
+
}
|
|
199
|
+
if (!('phoneNumber' in action.payload.value) || !('countryCode' in action.payload.value)) {
|
|
200
|
+
throw new Error('Value argument must contain a phoneNumber and countryCode property');
|
|
201
|
+
}
|
|
202
|
+
collector.input.value = action.payload.value;
|
|
203
|
+
}
|
|
204
|
+
if (collector.type === 'FidoRegistrationCollector') {
|
|
205
|
+
if (typeof action.payload.id !== 'string') {
|
|
206
|
+
throw new Error('Index argument must be a string');
|
|
207
|
+
}
|
|
208
|
+
if (typeof action.payload.value !== 'object') {
|
|
209
|
+
throw new Error('Value argument must be an object');
|
|
210
|
+
}
|
|
211
|
+
if (!('attestationValue' in action.payload.value)) {
|
|
212
|
+
throw new Error('Value argument must contain an attestationValue property');
|
|
213
|
+
}
|
|
214
|
+
collector.input.value = action.payload.value;
|
|
215
|
+
}
|
|
216
|
+
if (collector.type === 'FidoAuthenticationCollector') {
|
|
217
|
+
if (typeof action.payload.id !== 'string') {
|
|
218
|
+
throw new Error('Index argument must be a string');
|
|
219
|
+
}
|
|
220
|
+
if (typeof action.payload.value !== 'object') {
|
|
221
|
+
throw new Error('Value argument must be an object');
|
|
222
|
+
}
|
|
223
|
+
if (!('assertionValue' in action.payload.value)) {
|
|
224
|
+
throw new Error('Value argument must contain an assertionValue property');
|
|
225
|
+
}
|
|
226
|
+
collector.input.value = action.payload.value;
|
|
227
|
+
}
|
|
141
228
|
});
|
|
142
229
|
});
|
|
143
230
|
//# sourceMappingURL=node.reducer.js.map
|