@prove-identity/prove-auth 2.14.0 → 2.15.1

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.
Files changed (33) hide show
  1. package/build/bundle/release/prove-auth.js +1 -1
  2. package/build/lib/index.d.ts +3 -2
  3. package/build/lib/index.js +1 -2
  4. package/build/lib/proveauth/authenticator-builder.d.ts +5 -0
  5. package/build/lib/proveauth/authenticator-builder.js +25 -2
  6. package/build/lib/proveauth/external/@authid/web-component/authid-web-component.d.ts +3 -0
  7. package/build/lib/proveauth/external/@authid/web-component/authid-web-component.js +55 -0
  8. package/build/lib/proveauth/instantlink.d.ts +2 -6
  9. package/build/lib/proveauth/instantlink.js +1 -11
  10. package/build/lib/proveauth/internal/auth-request.d.ts +5 -1
  11. package/build/lib/proveauth/internal/auth-response.d.ts +24 -28
  12. package/build/lib/proveauth/internal/auth-session.d.ts +2 -1
  13. package/build/lib/proveauth/internal/auth-session.js +1 -0
  14. package/build/lib/proveauth/internal/auth-token-claims.d.ts +21 -3
  15. package/build/lib/proveauth/internal/device-passive-silent-step.js +5 -6
  16. package/build/lib/proveauth/internal/device-passive-step.js +7 -5
  17. package/build/lib/proveauth/internal/mobile-instant-step.js +2 -2
  18. package/build/lib/proveauth/internal/mobile-instantlink-step.d.ts +0 -3
  19. package/build/lib/proveauth/internal/mobile-instantlink-step.js +22 -122
  20. package/build/lib/proveauth/internal/mobile-otp-step.js +3 -3
  21. package/build/lib/proveauth/internal/platform.d.ts +11 -0
  22. package/build/lib/proveauth/internal/report-error-step.js +5 -2
  23. package/build/lib/proveauth/internal/user-mobileactive-step.js +1 -3
  24. package/build/lib/proveauth/internal/user-ppb-steps.d.ts +24 -0
  25. package/build/lib/proveauth/internal/user-ppb-steps.js +103 -0
  26. package/build/lib/proveauth/internal/user-present-step.js +1 -3
  27. package/build/lib/proveauth/internal/web-platform.d.ts +3 -1
  28. package/build/lib/proveauth/internal/web-platform.js +101 -0
  29. package/build/lib/proveauth/ppb.d.ts +9 -0
  30. package/build/lib/proveauth/ppb.js +2 -0
  31. package/build/lib/proveauth/version.d.ts +2 -2
  32. package/build/lib/proveauth/version.js +2 -2
  33. package/package.json +1 -1
@@ -9,7 +9,6 @@ const phone_number_input_1 = require("./phone-number-input");
9
9
  const auth_error_1 = __importDefault(require("./auth-error"));
10
10
  const auth_status_actions_1 = require("./auth-status-actions");
11
11
  const mobile_otp_step_1 = __importDefault(require("./mobile-otp-step"));
12
- const SIMULATED_LINK_CLICK_DELAY = 100;
13
12
  class MobileInstantLinkStep extends auth_status_actions_1.AuthStatusActions {
14
13
  constructor(startStep, retryStep, getDeviceIp) {
15
14
  super();
@@ -19,16 +18,8 @@ class MobileInstantLinkStep extends auth_status_actions_1.AuthStatusActions {
19
18
  this.retryStep = retryStep;
20
19
  this.getDeviceIp = getDeviceIp !== null && getDeviceIp !== void 0 ? getDeviceIp : (() => null);
21
20
  }
22
- isTestMode(session) {
23
- var _a, _b, _c;
24
- var testMode = false;
25
- if ((_c = (_b = (_a = session.claims) === null || _a === void 0 ? void 0 : _a.auth.subs.mob) === null || _b === void 0 ? void 0 : _b.auths.inln) === null || _c === void 0 ? void 0 : _c.tme) {
26
- testMode = true;
27
- }
28
- return testMode;
29
- }
30
21
  execute(session) {
31
- this.log.trace('Executing');
22
+ this.log.debug('Executing');
32
23
  return new Promise((resolve, reject) => {
33
24
  var _a, _b, _c;
34
25
  var phoneNumberNeeded = true;
@@ -40,34 +31,6 @@ class MobileInstantLinkStep extends auth_status_actions_1.AuthStatusActions {
40
31
  this.waitForStatus(session).then(resolve).catch(reject);
41
32
  });
42
33
  }
43
- getInstantLinkError(responseData) {
44
- const errorCode = responseData.code;
45
- var errorMessage = '';
46
- if (errorCode) {
47
- errorMessage += `Error Code: ${responseData.code}, `;
48
- }
49
- let instantLinkError;
50
- if (errorCode === 10005) {
51
- if (responseData.message) {
52
- errorMessage += `${responseData.message}`;
53
- }
54
- else {
55
- errorMessage += `Max number of retires reached.`;
56
- }
57
- instantLinkError = new instantlink_1.InstantLinkMaxRetryError(errorMessage, responseData.code);
58
- }
59
- else {
60
- if (responseData.message) {
61
- errorMessage += `${responseData.message}`;
62
- }
63
- else {
64
- errorMessage += `Error validating phone number`;
65
- }
66
- instantLinkError = new phone_number_input_1.PhoneValidationError(errorMessage, responseData.code);
67
- }
68
- this.log.error(`Server reports instant link error: ${errorMessage}`);
69
- return instantLinkError;
70
- }
71
34
  runStartStep(session, phoneNumberNeeded, instantLinkError) {
72
35
  return new Promise((resolve, reject) => {
73
36
  if (this.startStep) {
@@ -90,50 +53,30 @@ class MobileInstantLinkStep extends auth_status_actions_1.AuthStatusActions {
90
53
  reject(new auth_error_1.default(authResponse.error.message, authResponse.error.code, response.next, false));
91
54
  }
92
55
  else if (authResponse.data) {
93
- const errorCode = authResponse.data.code;
56
+ const data = authResponse.data;
57
+ const errorCode = data.code;
94
58
  var errorMessage = '';
95
59
  if (errorCode) {
96
- errorMessage += `Error Code: ${authResponse.data.code}, `;
60
+ errorMessage += `Error Code: ${errorCode}, `;
97
61
  }
98
- if (errorCode === 10005) {
99
- if (authResponse.data.message) {
100
- errorMessage += `${authResponse.data.message}`;
101
- }
102
- else {
103
- errorMessage += `Max number of retires reached.`;
104
- }
105
- let maxRetryError = new instantlink_1.InstantLinkMaxRetryError(errorMessage, authResponse.data.code);
106
- if (this.retryStep) {
107
- this.runRetryStep(session, maxRetryError).then(resolve).catch(reject);
108
- }
109
- else {
110
- this.log.error('Max number of retires reached but retry step is undefined.');
111
- }
62
+ if (data.message) {
63
+ errorMessage += `${data.message}`;
112
64
  }
113
65
  else {
114
- if (authResponse.data.message) {
115
- errorMessage += `${authResponse.data.message}`;
116
- }
117
- else {
118
- errorMessage += `Error validating phone number.`;
119
- }
120
- let invalidPhoneError = new phone_number_input_1.PhoneValidationError(errorMessage, authResponse.data.code);
121
- this.runStartStep(session, phoneNumberNeeded, invalidPhoneError)
122
- .then(resolve)
123
- .catch(reject);
66
+ errorMessage += `Error validating phone number.`;
124
67
  }
68
+ let invalidPhoneError = new phone_number_input_1.PhoneValidationError(errorMessage, data.code);
69
+ this.runStartStep(session, phoneNumberNeeded, invalidPhoneError)
70
+ .then(resolve)
71
+ .catch(reject);
125
72
  }
126
73
  else {
127
- this.handleTestMode(session)
128
- .then(() => {
129
- if (this.retryStep) {
130
- this.runRetryStep(session).then(resolve).catch(reject);
131
- }
132
- else {
133
- resolve(authResponse.next);
134
- }
135
- })
136
- .catch(reject);
74
+ if (this.retryStep) {
75
+ this.runRetryStep(session).then(resolve).catch(reject);
76
+ }
77
+ else {
78
+ resolve(authResponse.next);
79
+ }
137
80
  }
138
81
  })
139
82
  .catch(reject);
@@ -146,11 +89,11 @@ class MobileInstantLinkStep extends auth_status_actions_1.AuthStatusActions {
146
89
  }
147
90
  });
148
91
  }
149
- runRetryStep(session, instantLinkError) {
92
+ runRetryStep(session) {
150
93
  return new Promise((resolve, reject) => {
151
94
  if (this.retryStep) {
152
95
  this.retryStep
153
- .execute(instantLinkError)
96
+ .execute()
154
97
  .then((resultType) => {
155
98
  if (resultType === instantlink_1.InstantLinkResultType.OnResend) {
156
99
  session
@@ -163,26 +106,8 @@ class MobileInstantLinkStep extends auth_status_actions_1.AuthStatusActions {
163
106
  if (authResponse.error) {
164
107
  reject(new auth_error_1.default(authResponse.error.message, authResponse.error.code, response.next, false));
165
108
  }
166
- else if (authResponse.data) {
167
- const errorCode = authResponse.data.code;
168
- var errorMessage = '';
169
- if (errorCode) {
170
- errorMessage += `Error Code: ${authResponse.data.code}, `;
171
- }
172
- if (authResponse.data.message) {
173
- errorMessage += `${authResponse.data.message}`;
174
- }
175
- else {
176
- errorMessage += `Max number of retires reached.`;
177
- }
178
- let maxRetryError = new instantlink_1.InstantLinkMaxRetryError(errorMessage, authResponse.data.code);
179
- this.runRetryStep(session, maxRetryError).then(resolve).catch(reject);
180
- }
181
109
  else {
182
- this.handleTestMode(session)
183
- .then(() => this.runRetryStep(session))
184
- .then(resolve)
185
- .catch(reject);
110
+ this.runRetryStep(session);
186
111
  }
187
112
  })
188
113
  .catch(reject);
@@ -191,42 +116,17 @@ class MobileInstantLinkStep extends auth_status_actions_1.AuthStatusActions {
191
116
  this.runStartStep(session, true).then(resolve).catch(reject);
192
117
  }
193
118
  else {
194
- this.log.warn('Unkown enum of ', resultType);
119
+ this.log.warn('Unknown enum of ', resultType);
195
120
  }
196
121
  })
197
122
  .catch(reject);
198
123
  }
199
124
  else {
200
- this.log.debug("Retry step doesn't exsist, skip.");
125
+ this.log.debug("Retry step doesn't exist, skip.");
201
126
  resolve('');
202
127
  }
203
128
  });
204
129
  }
205
- handleTestMode(session) {
206
- return new Promise((resolve, reject) => {
207
- if (this.isTestMode(session)) {
208
- this.log.info('Simulating user clicking the instant link');
209
- setTimeout(() => {
210
- session.platform
211
- .fetch(session.backendOrigin +
212
- '/v1/client/mobile/instantlink/finish?token=' +
213
- encodeURIComponent(session.authToken) +
214
- '&vfp=test-vfp', {
215
- mode: 'no-cors',
216
- method: 'GET',
217
- })
218
- .then(() => resolve)
219
- .catch((e) => {
220
- this.log.error('Calling AuthFinish in test mode has failed: ', auth_error_1.default.extractMessage(e));
221
- reject(e);
222
- });
223
- }, SIMULATED_LINK_CLICK_DELAY);
224
- }
225
- else {
226
- resolve();
227
- }
228
- });
229
- }
230
130
  }
231
131
  MobileInstantLinkStep.NAME = 'mobile/instantlink';
232
132
  exports.default = MobileInstantLinkStep;
@@ -69,7 +69,7 @@ class MobileOtpStep {
69
69
  reject(new auth_error_1.default(authResponse.error.message, authResponse.error.code, response.next, false));
70
70
  }
71
71
  else if (authResponse.data) {
72
- let data = authResponse.data;
72
+ const data = authResponse.data;
73
73
  var errorMessage = '';
74
74
  if (data === null || data === void 0 ? void 0 : data.code) {
75
75
  errorMessage += `Error Code: ${data.code}, `;
@@ -170,7 +170,7 @@ class MobileOtpStep {
170
170
  reject(new auth_error_1.default(authResponse.error.message, authResponse.error.code, response.next, false));
171
171
  }
172
172
  else if (authResponse.data) {
173
- let data = authResponse.data;
173
+ const data = authResponse.data;
174
174
  var errorMessage = '';
175
175
  if (data === null || data === void 0 ? void 0 : data.code) {
176
176
  errorMessage += `Error Code: ${data.code}, `;
@@ -181,7 +181,7 @@ class MobileOtpStep {
181
181
  else {
182
182
  errorMessage += `Error validating OTP`;
183
183
  }
184
- let otpError = new otp_1.OtpError(errorMessage, data === null || data === void 0 ? void 0 : data.code);
184
+ const otpError = new otp_1.OtpError(errorMessage, data === null || data === void 0 ? void 0 : data.code);
185
185
  this.log.error(`Server reports invalid OTP: ${errorMessage}`);
186
186
  this.runOtpFinishStep(session, otpStartStep, otpFinishStep, phoneNumberNeeded, otpError)
187
187
  .then(resolve)
@@ -4,6 +4,7 @@ import { AuthRequest } from './auth-request';
4
4
  import AuthResponse from './auth-response';
5
5
  import DeviceAuth, { DeviceRegistration } from './device-auth';
6
6
  import { Agent } from '@fingerprintjs/fingerprintjs-pro';
7
+ import { PpbOperation } from '../ppb';
7
8
  export declare const DEVICE_CAPABILITY_WEBAUTHN = "webauthn";
8
9
  export interface MessageChannel {
9
10
  addEventListener: (type: string, listener: (event: any) => void) => void;
@@ -27,6 +28,15 @@ export interface AuthSessionIntegration {
27
28
  getDeviceRegistration: () => Promise<DeviceRegistration | null>;
28
29
  fetchFromBackend: (query: string, body: AuthRequest) => Promise<AuthResponse>;
29
30
  }
31
+ export interface PpbAuthResult {
32
+ authIdSuccess?: boolean;
33
+ }
34
+ export interface PpbAuthOptions {
35
+ authIdEndpointUrl?: string;
36
+ authIdOperation?: PpbOperation;
37
+ authIdOperationId?: string;
38
+ authIdOneTimeSecret?: string;
39
+ }
30
40
  export default interface Platform {
31
41
  readonly webauthn: WebAuthN;
32
42
  readonly deviceAuth: DeviceAuth;
@@ -43,6 +53,7 @@ export default interface Platform {
43
53
  getFpPromise: () => Promise<Agent> | undefined;
44
54
  setFpPromise: (fpPromise: Promise<Agent>) => void;
45
55
  getOrigin: () => string;
56
+ ppbAuthenticate: (options: PpbAuthOptions) => Promise<PpbAuthResult>;
46
57
  }
47
58
  export declare function stringToArrayBuffer(input: string): ArrayBuffer;
48
59
  export declare function arrayBufferToString(input: ArrayBuffer): string;
@@ -16,6 +16,7 @@ const mobile_otp_step_1 = __importDefault(require("./mobile-otp-step"));
16
16
  const user_present_step_1 = __importDefault(require("./user-present-step"));
17
17
  const device_passive_stepup_step_1 = __importDefault(require("./device-passive-stepup-step"));
18
18
  const device_universal_redirect_steps_1 = require("./device-universal-redirect-steps");
19
+ const user_ppb_steps_1 = require("./user-ppb-steps");
19
20
  class ReportErrorStep {
20
21
  constructor(error) {
21
22
  this.logger = logger_1.LoggerFactory.getLogger('report-error-step');
@@ -82,11 +83,13 @@ ReportErrorStep.endpointMap = new Map([
82
83
  [device_passive_register_step_1.default.NAME, 'device/fido2'],
83
84
  [device_passive_verify_step_1.default.NAME, 'device/fido2'],
84
85
  [device_passive_stepup_step_1.default.NAME, 'device/fido2'],
86
+ [device_universal_redirect_steps_1.DeviceUniversalRedirectExchangeStep.NAME, 'device/universal'],
87
+ [device_universal_redirect_steps_1.DeviceUniversalRedirectFinishStep.NAME, 'device/universal'],
85
88
  [mobile_instant_step_1.default.NAME, 'mobile/instant'],
86
89
  [mobile_instantlink_step_1.default.NAME, 'mobile/instantlink'],
87
90
  [mobile_otp_step_1.default.NAME, 'mobile/otp'],
88
91
  [user_present_step_1.default.NAME, 'user/mobileactive'],
89
- [device_universal_redirect_steps_1.DeviceUniversalRedirectExchangeStep.NAME, 'device/universal'],
90
- [device_universal_redirect_steps_1.DeviceUniversalRedirectFinishStep.NAME, 'device/universal'],
92
+ [user_ppb_steps_1.UserPpbEnrollStep.NAME, 'user/ppb'],
93
+ [user_ppb_steps_1.UserPpbVerifyStep.NAME, 'user/ppb'],
91
94
  ]);
92
95
  exports.default = ReportErrorStep;
@@ -9,9 +9,7 @@ class UserMobileActiveStep {
9
9
  this.name = UserMobileActiveStep.NAME;
10
10
  }
11
11
  execute(session) {
12
- return new Promise((resolve, reject) => {
13
- reject(new auth_error_1.default(`Step ${this.name} is not supported yet`));
14
- });
12
+ return Promise.reject(new auth_error_1.default(`Step ${this.name} is not supported`));
15
13
  }
16
14
  }
17
15
  UserMobileActiveStep.NAME = 'user/mobileactive';
@@ -0,0 +1,24 @@
1
+ import AuthStep from './auth-step';
2
+ import AuthSession from './auth-session';
3
+ import { PpbFinishStep, PpbOperation, PpbStartStep } from '../ppb';
4
+ declare abstract class UserPpbBaseStep implements AuthStep {
5
+ readonly name: string;
6
+ private readonly log;
7
+ private readonly enabled;
8
+ private readonly operation;
9
+ private readonly startStep;
10
+ private readonly finishStep;
11
+ constructor(enabled: boolean, operation: PpbOperation, startStep?: PpbStartStep, finishStep?: PpbFinishStep);
12
+ execute(session: AuthSession): Promise<string>;
13
+ }
14
+ export declare class UserPpbEnrollStep extends UserPpbBaseStep {
15
+ static readonly NAME = "user/ppb/register";
16
+ readonly name = "user/ppb/register";
17
+ constructor(enabled: boolean, startStep?: PpbStartStep, finishStep?: PpbFinishStep);
18
+ }
19
+ export declare class UserPpbVerifyStep extends UserPpbBaseStep {
20
+ static readonly NAME = "user/ppb/verify";
21
+ readonly name = "user/ppb/verify";
22
+ constructor(enabled: boolean, startStep?: PpbStartStep, finishStep?: PpbFinishStep);
23
+ }
24
+ export {};
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.UserPpbVerifyStep = exports.UserPpbEnrollStep = void 0;
7
+ const logger_1 = require("../common/logger");
8
+ const auth_error_1 = __importDefault(require("./auth-error"));
9
+ class UserPpbBaseStep {
10
+ constructor(enabled, operation, startStep, finishStep) {
11
+ this.log = logger_1.LoggerFactory.getLogger('user-ppb-base-step');
12
+ this.enabled = enabled;
13
+ this.operation = operation;
14
+ this.startStep = startStep;
15
+ this.finishStep = finishStep;
16
+ }
17
+ execute(session) {
18
+ if (!this.enabled) {
19
+ return Promise.reject(new auth_error_1.default('PPB is not enabled'));
20
+ }
21
+ const data = session.lastData;
22
+ if (!data || !data.ppb) {
23
+ return Promise.reject(new auth_error_1.default('PPB session is not initialized'));
24
+ }
25
+ return new Promise((resolve, reject) => {
26
+ const callStart = () => {
27
+ try {
28
+ if (this.startStep) {
29
+ return this.startStep.execute(this.operation);
30
+ }
31
+ else {
32
+ return Promise.resolve();
33
+ }
34
+ }
35
+ catch (e) {
36
+ this.log.warn('PPB start step has failed:', e);
37
+ return Promise.reject(e);
38
+ }
39
+ };
40
+ const callFinish = (error) => {
41
+ try {
42
+ if (this.finishStep) {
43
+ return this.finishStep.execute(this.operation, error);
44
+ }
45
+ else {
46
+ return Promise.resolve();
47
+ }
48
+ }
49
+ catch (e) {
50
+ this.log.warn('PPB finish step has failed:', e);
51
+ return Promise.reject(e);
52
+ }
53
+ };
54
+ callStart()
55
+ .then(() => {
56
+ var _a, _b, _c, _d, _e;
57
+ return session.platform.ppbAuthenticate({
58
+ authIdOperation: this.operation,
59
+ authIdEndpointUrl: (_c = (_b = (_a = session.claims) === null || _a === void 0 ? void 0 : _a.auth.subs.usr) === null || _b === void 0 ? void 0 : _b.auths.ppb) === null || _c === void 0 ? void 0 : _c.endp,
60
+ authIdOperationId: (_d = data.ppb) === null || _d === void 0 ? void 0 : _d.operationId,
61
+ authIdOneTimeSecret: (_e = data.ppb) === null || _e === void 0 ? void 0 : _e.oneTimeSecret,
62
+ });
63
+ })
64
+ .catch(reject)
65
+ .then((result) => {
66
+ var _a;
67
+ this.log.info('PPB authentication result', result);
68
+ return session.fetchFromBackend('/v1/client/user/ppb/finish', {
69
+ requestId: crypto.randomUUID(),
70
+ operationId: (_a = data.ppb) === null || _a === void 0 ? void 0 : _a.operationId,
71
+ });
72
+ })
73
+ .then((response) => {
74
+ var _a, _b;
75
+ const ppbResponse = response;
76
+ if (ppbResponse.error) {
77
+ const message = (_b = (_a = response.error) === null || _a === void 0 ? void 0 : _a.message) !== null && _b !== void 0 ? _b : 'PPB authentication failed';
78
+ callFinish(new Error(message)).then(() => reject(new auth_error_1.default(response.error.message, response.error.code, response.next, false)));
79
+ }
80
+ else {
81
+ callFinish().then(() => resolve(ppbResponse.next));
82
+ }
83
+ })
84
+ .catch(reject);
85
+ });
86
+ }
87
+ }
88
+ class UserPpbEnrollStep extends UserPpbBaseStep {
89
+ constructor(enabled, startStep, finishStep) {
90
+ super(enabled, 'enroll', startStep, finishStep);
91
+ this.name = UserPpbEnrollStep.NAME;
92
+ }
93
+ }
94
+ UserPpbEnrollStep.NAME = 'user/ppb/register';
95
+ exports.UserPpbEnrollStep = UserPpbEnrollStep;
96
+ class UserPpbVerifyStep extends UserPpbBaseStep {
97
+ constructor(enabled, startStep, finishStep) {
98
+ super(enabled, 'verify', startStep, finishStep);
99
+ this.name = UserPpbVerifyStep.NAME;
100
+ }
101
+ }
102
+ UserPpbVerifyStep.NAME = 'user/ppb/verify';
103
+ exports.UserPpbVerifyStep = UserPpbVerifyStep;
@@ -9,9 +9,7 @@ class UserPresentStep {
9
9
  this.name = UserPresentStep.NAME;
10
10
  }
11
11
  execute(session) {
12
- return new Promise((resolve, reject) => {
13
- reject(new auth_error_1.default(`Step ${this.name} is not supported yet`));
14
- });
12
+ return Promise.reject(new auth_error_1.default(`Step ${this.name} is not supported`));
15
13
  }
16
14
  }
17
15
  UserPresentStep.NAME = 'user/present';
@@ -1,5 +1,5 @@
1
1
  import { AuthenticatorBuilder } from '@prove-identity/mobile-auth';
2
- import Platform, { AuthSessionIntegration, MessageChannel, RequestSigner } from './platform';
2
+ import Platform, { AuthSessionIntegration, MessageChannel, PpbAuthOptions, PpbAuthResult, RequestSigner } from './platform';
3
3
  import WebDeviceAuth from './web-device-auth';
4
4
  import { Agent } from '@fingerprintjs/fingerprintjs-pro';
5
5
  export declare class WebSocketMessageChannel implements MessageChannel {
@@ -10,6 +10,7 @@ export declare class WebSocketMessageChannel implements MessageChannel {
10
10
  close(): void;
11
11
  }
12
12
  export declare class WebPlatform implements Platform {
13
+ private readonly log;
13
14
  private fpPromise;
14
15
  readonly webauthn: {
15
16
  getCredentials: (options?: CredentialRequestOptions) => Promise<CredentialType | null>;
@@ -22,6 +23,7 @@ export declare class WebPlatform implements Platform {
22
23
  fetch(input: string, init?: RequestInit): Promise<Response>;
23
24
  createMessageChannel(input: string): MessageChannel;
24
25
  createRequestSigner(session: AuthSessionIntegration): RequestSigner;
26
+ ppbAuthenticate(options: PpbAuthOptions): Promise<PpbAuthResult>;
25
27
  private getBrowserName;
26
28
  private getBrowserVersion;
27
29
  getOSName(): string;
@@ -1,4 +1,13 @@
1
1
  "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
2
11
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
13
  };
@@ -6,6 +15,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
15
  exports.WebPlatform = exports.WebSocketMessageChannel = void 0;
7
16
  const mobile_auth_1 = require("@prove-identity/mobile-auth");
8
17
  const platform_1 = require("./platform");
18
+ const logger_1 = require("../common/logger");
9
19
  const request_signer_v3_1 = __importDefault(require("./request-signer-v3"));
10
20
  const web_device_auth_1 = __importDefault(require("./web-device-auth"));
11
21
  class WebSocketMessageChannel {
@@ -25,6 +35,7 @@ class WebSocketMessageChannel {
25
35
  exports.WebSocketMessageChannel = WebSocketMessageChannel;
26
36
  class WebPlatform {
27
37
  constructor() {
38
+ this.log = logger_1.LoggerFactory.getLogger('web-platform');
28
39
  this.webauthn = {
29
40
  getCredentials: (options) => {
30
41
  return navigator.credentials.get(options);
@@ -53,6 +64,96 @@ class WebPlatform {
53
64
  createRequestSigner(session) {
54
65
  return new request_signer_v3_1.default(session);
55
66
  }
67
+ ppbAuthenticate(options) {
68
+ return __awaiter(this, void 0, void 0, function* () {
69
+ const operationMap = new Map([
70
+ ['enroll', 'i'],
71
+ ['verify', 't'],
72
+ ]);
73
+ if (!options.authIdEndpointUrl) {
74
+ return Promise.reject('AuthID API endpoint URL is missing');
75
+ }
76
+ if (!options.authIdOperation) {
77
+ return Promise.reject('AuthID API operation is missing');
78
+ }
79
+ if (!operationMap.has(options.authIdOperation)) {
80
+ return Promise.reject('AuthID API operation is not recognized');
81
+ }
82
+ if (!options.authIdOperationId) {
83
+ return Promise.reject('AuthID operation ID is missing');
84
+ }
85
+ if (!options.authIdOneTimeSecret) {
86
+ return Promise.reject('AuthID operation secret is missing');
87
+ }
88
+ const componentName = 'authid-component';
89
+ try {
90
+ const authId = require('../external/@authid/web-component/authid-web-component');
91
+ if (!authId) {
92
+ return Promise.reject('Failed to load PPB Auth web component');
93
+ }
94
+ if (!window.customElements.get(componentName)) {
95
+ window.customElements.define(componentName, authId.AuthIDComponent);
96
+ }
97
+ yield window.customElements.whenDefined(componentName);
98
+ }
99
+ catch (e) {
100
+ this.log.error(e);
101
+ return Promise.reject(new Error('Failed to initialize PPB Auth web component'));
102
+ }
103
+ return new Promise((resolve, reject) => {
104
+ const existingComponent = document.querySelector(componentName);
105
+ if (existingComponent) {
106
+ this.log.trace('Removing existing component', componentName);
107
+ existingComponent.remove();
108
+ }
109
+ const authIdComponent = document.createElement(componentName);
110
+ const url = `${options.authIdEndpointUrl}/?` +
111
+ `${operationMap.get(options.authIdOperation)}=${options.authIdOperationId}&` +
112
+ `s=${options.authIdOneTimeSecret}`;
113
+ authIdComponent.setAttribute('data-url', url);
114
+ document.body.appendChild(authIdComponent);
115
+ const handleAuthDone = (success) => __awaiter(this, void 0, void 0, function* () {
116
+ window.removeEventListener('message', handleMessage);
117
+ this.log.trace('On PPB auth done');
118
+ resolve({ authIdSuccess: success });
119
+ });
120
+ const handleMessage = (event) => {
121
+ this.log.debug('PPB event', event.data);
122
+ if (event.data.success) {
123
+ const authIdComponent = document.querySelector(componentName);
124
+ if (authIdComponent) {
125
+ authIdComponent.remove();
126
+ }
127
+ handleAuthDone(true);
128
+ }
129
+ else {
130
+ switch (event.data.pageName) {
131
+ case 'documentFailedPage':
132
+ case 'documentFailedNonMobilePage':
133
+ case 'networkErrorPage':
134
+ case 'livenessErrorPage':
135
+ case 'docScanWasmTimeoutPage':
136
+ case 'requestTimeoutPage':
137
+ case 'transactionNotValidPage':
138
+ case 'transactionMaxAttemptsPage':
139
+ case 'QRCodePage':
140
+ return;
141
+ case 'verifiedMatchFailPage':
142
+ case 'verifyDeclinedPage':
143
+ authIdComponent.remove();
144
+ case 'docScanResolutionTooLowPage':
145
+ case 'videoDeviceNotFoundPage':
146
+ case 'standardErrorPage':
147
+ case 'defaultFailedPage':
148
+ handleAuthDone(false);
149
+ break;
150
+ }
151
+ }
152
+ };
153
+ window.addEventListener('message', handleMessage);
154
+ });
155
+ });
156
+ }
56
157
  getBrowserName() {
57
158
  const agent = navigator.userAgent;
58
159
  let browserName;
@@ -0,0 +1,9 @@
1
+ export type PpbOperation = 'enroll' | 'verify';
2
+ export interface PpbStartStep {
3
+ execute: (operation: PpbOperation) => Promise<void>;
4
+ }
5
+ export interface PpbFinishStep {
6
+ execute: (operation: PpbOperation, error?: Error) => Promise<void>;
7
+ }
8
+ export type PpbStartStepFn = (operation: PpbOperation) => Promise<void>;
9
+ export type PpbFinishStepFn = (operation: PpbOperation, error?: Error) => Promise<void>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,3 +1,3 @@
1
- export declare const VERSION = "2.14.0";
2
- export declare const API_CONTRACT_VERSION = "2.14.0";
1
+ export declare const VERSION = "2.15.1";
2
+ export declare const API_CONTRACT_VERSION = "2.15.1";
3
3
  export declare const USER_AGENT_VERSIONS: string;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.USER_AGENT_VERSIONS = exports.API_CONTRACT_VERSION = exports.VERSION = void 0;
4
- exports.VERSION = '2.14.0';
5
- exports.API_CONTRACT_VERSION = '2.14.0';
4
+ exports.VERSION = '2.15.1';
5
+ exports.API_CONTRACT_VERSION = '2.15.1';
6
6
  exports.USER_AGENT_VERSIONS = `ProveAuth/${exports.VERSION} Contract/${exports.API_CONTRACT_VERSION} WEB/1`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prove-identity/prove-auth",
3
- "version": "2.14.0",
3
+ "version": "2.15.1",
4
4
  "description": "Prove Auth SDK for Web",
5
5
  "main": "build/lib/index.js",
6
6
  "files": [