@prove-identity/prove-auth 2.13.1 → 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 (39) 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 -3
  11. package/build/lib/proveauth/internal/auth-response.d.ts +24 -28
  12. package/build/lib/proveauth/internal/auth-session.d.ts +6 -1
  13. package/build/lib/proveauth/internal/auth-session.js +34 -7
  14. package/build/lib/proveauth/internal/auth-token-claims.d.ts +22 -3
  15. package/build/lib/proveauth/internal/device-passive-register-step.js +8 -9
  16. package/build/lib/proveauth/internal/device-passive-silent-step.js +13 -6
  17. package/build/lib/proveauth/internal/device-passive-step.js +10 -5
  18. package/build/lib/proveauth/internal/device-passive-stepup-step.js +1 -19
  19. package/build/lib/proveauth/internal/device-passive-verify-step.js +2 -18
  20. package/build/lib/proveauth/internal/main-authenticator.js +3 -0
  21. package/build/lib/proveauth/internal/mobile-instant-step.js +2 -2
  22. package/build/lib/proveauth/internal/mobile-instantlink-step.d.ts +0 -3
  23. package/build/lib/proveauth/internal/mobile-instantlink-step.js +22 -122
  24. package/build/lib/proveauth/internal/mobile-otp-step.js +3 -3
  25. package/build/lib/proveauth/internal/platform.d.ts +11 -0
  26. package/build/lib/proveauth/internal/report-error-step.js +5 -2
  27. package/build/lib/proveauth/internal/settings.d.ts +3 -0
  28. package/build/lib/proveauth/internal/settings.js +14 -0
  29. package/build/lib/proveauth/internal/user-mobileactive-step.js +1 -3
  30. package/build/lib/proveauth/internal/user-ppb-steps.d.ts +24 -0
  31. package/build/lib/proveauth/internal/user-ppb-steps.js +103 -0
  32. package/build/lib/proveauth/internal/user-present-step.js +1 -3
  33. package/build/lib/proveauth/internal/web-platform.d.ts +3 -1
  34. package/build/lib/proveauth/internal/web-platform.js +101 -0
  35. package/build/lib/proveauth/ppb.d.ts +9 -0
  36. package/build/lib/proveauth/ppb.js +2 -0
  37. package/build/lib/proveauth/version.d.ts +2 -2
  38. package/build/lib/proveauth/version.js +2 -2
  39. package/package.json +1 -1
@@ -21,6 +21,7 @@ const main_authenticator_1 = __importDefault(require("./internal/main-authentica
21
21
  const logger_1 = require("./common/logger");
22
22
  const settings_1 = __importDefault(require("./internal/settings"));
23
23
  const device_context_options_1 = require("./device-context-options");
24
+ const user_ppb_steps_1 = require("./internal/user-ppb-steps");
24
25
  var DeviceRole;
25
26
  (function (DeviceRole) {
26
27
  DeviceRole[DeviceRole["Primary"] = 0] = "Primary";
@@ -36,6 +37,7 @@ class AuthenticatorBuilder {
36
37
  this.role = DeviceRole.Primary;
37
38
  this.mobileAuthImplementation = MobileAuthImplementation.Fetch;
38
39
  this.upkEnabled = false;
40
+ this.ppbEnabled = false;
39
41
  this.log = logger_1.LoggerFactory.getLogger('authenticator-builder');
40
42
  if (typeof window !== 'undefined') {
41
43
  this.storage = window.localStorage;
@@ -131,6 +133,22 @@ class AuthenticatorBuilder {
131
133
  this.upkEnabled = this.userConsentStep != null;
132
134
  return this;
133
135
  }
136
+ withPrivacyPreservingBiometrics(startStep, finishStep) {
137
+ this.ppbEnabled = true;
138
+ if (typeof startStep === 'function') {
139
+ this.ppbStartStep = { execute: startStep };
140
+ }
141
+ else {
142
+ this.ppbStartStep = startStep;
143
+ }
144
+ if (typeof finishStep === 'function') {
145
+ this.ppbFinishStep = { execute: finishStep };
146
+ }
147
+ else {
148
+ this.ppbFinishStep = finishStep;
149
+ }
150
+ return this;
151
+ }
134
152
  getUrlsByBuildConfig(buildConfig) {
135
153
  switch (buildConfig) {
136
154
  case device_context_options_1.BuildConfig.US_PROD:
@@ -144,7 +162,8 @@ class AuthenticatorBuilder {
144
162
  device_context_options_1.ProveAuthProxyEndpoint.DEFAULT_US_UAT_ENDPOINT.toString(),
145
163
  ];
146
164
  case device_context_options_1.BuildConfig.DEV:
147
- this.log.debug("Recommended for Prove's internal testing only, BuildConfig.DEV might need custom endpoint URL and custom script URL values to bypass ad blockers");
165
+ this.log.debug("Recommended for Prove's internal testing only, BuildConfig.DEV " +
166
+ 'might need custom endpoint URL and custom script URL values to bypass ad blockers');
148
167
  return [undefined, undefined];
149
168
  default:
150
169
  this.log.warn('Unknown BuildConfig value: ' + buildConfig);
@@ -237,8 +256,10 @@ class AuthenticatorBuilder {
237
256
  new mobile_instant_step_1.default(this.mobileAuthImplementation, this.getDeviceIp),
238
257
  new mobile_instantlink_step_1.default(this.instantLinkStartStep, this.instantLinkRetryStep, this.getDeviceIp),
239
258
  new mobile_otp_step_1.default(this.otpStartStep, this.otpFinishStep),
240
- new user_mobileactive_step_1.default(),
241
259
  new scan_message_step_1.default(this.authMessageHandler),
260
+ new user_mobileactive_step_1.default(),
261
+ new user_ppb_steps_1.UserPpbEnrollStep(this.ppbEnabled, this.ppbStartStep, this.ppbFinishStep),
262
+ new user_ppb_steps_1.UserPpbVerifyStep(this.ppbEnabled, this.ppbStartStep, this.ppbFinishStep),
242
263
  ]);
243
264
  }
244
265
  else {
@@ -246,6 +267,8 @@ class AuthenticatorBuilder {
246
267
  new device_passive_step_1.default(this.getDisplayName, undefined, this.role),
247
268
  new mobile_instant_step_1.default(this.mobileAuthImplementation, this.getDeviceIp),
248
269
  new mobile_instantlink_step_1.default(this.instantLinkStartStep, this.instantLinkRetryStep, this.getDeviceIp),
270
+ new user_ppb_steps_1.UserPpbEnrollStep(this.ppbEnabled, this.ppbStartStep, this.ppbFinishStep),
271
+ new user_ppb_steps_1.UserPpbVerifyStep(this.ppbEnabled, this.ppbStartStep, this.ppbFinishStep),
249
272
  ]);
250
273
  }
251
274
  }
@@ -0,0 +1,3 @@
1
+ declare class AuthIDComponent extends HTMLElement {
2
+ connectedCallback(): void;
3
+ }
@@ -0,0 +1,55 @@
1
+ class AuthIDComponent extends HTMLElement {
2
+ connectedCallback() {
3
+ const dataUrl = this.getAttribute('data-url');
4
+ if (!dataUrl) {
5
+ throw new Error('Missing data-url configuration!');
6
+ }
7
+ let dataTarget = this.getAttribute('data-target');
8
+ if (!dataTarget || dataTarget === 'auto') {
9
+ dataTarget = /Mobi|Android/i.test(navigator.userAgent) ? 'mobile' : 'desktop';
10
+ }
11
+ const iframe = document.createElement('iframe');
12
+ iframe.setAttribute('allow', 'fullscreen *;camera *;encrypted-media *;');
13
+ iframe.setAttribute('src', dataUrl);
14
+ const styleNode = document.createElement('style');
15
+ styleNode.textContent =
16
+ 'div, iframe {' +
17
+ 'position: fixed;' +
18
+ 'top: 0;' +
19
+ 'left: 0;' +
20
+ 'height: 100vh;' +
21
+ 'width: 100vw;' +
22
+ 'border: 0;' +
23
+ 'padding: 0;' +
24
+ 'margin: 0;' +
25
+ '}';
26
+ const shadow = this.attachShadow({ mode: 'closed' });
27
+ shadow.appendChild(styleNode);
28
+ const container = document.createElement('div');
29
+ shadow.appendChild(container);
30
+ const dataWebauth = this.getAttribute('data-webauth');
31
+ if (dataWebauth && dataWebauth !== 'false' && dataWebauth !== 'no') {
32
+ const webauthHandler = document.createElement('script');
33
+ webauthHandler.setAttribute('src', dataUrl.replace('/?', '/webauthhandler.js?'));
34
+ shadow.appendChild(webauthHandler);
35
+ }
36
+ const dataControl = this.getAttribute('data-control');
37
+ if (dataControl && dataControl !== 'false' && dataControl !== 'no') {
38
+ const controlHandler = document.createElement('script');
39
+ controlHandler.setAttribute('src', dataUrl.replace('/?', '/controlhandler.js?'));
40
+ shadow.appendChild(controlHandler);
41
+ }
42
+ shadow.appendChild(iframe);
43
+ iframe.addEventListener('load', () => {
44
+ shadow.removeChild(container);
45
+ shadow.dispatchEvent(new CustomEvent('load', {
46
+ composed: true,
47
+ bubbles: true,
48
+ }));
49
+ }, { capture: true, once: true });
50
+ if (window.getComputedStyle(this)['z-index'] === 'auto') {
51
+ this.style['z-index'] = 1000;
52
+ }
53
+ }
54
+ }
55
+ window.customElements.define('authid-component', AuthIDComponent);
@@ -1,8 +1,4 @@
1
- import AuthError from './internal/auth-error';
2
1
  import PhoneNumberInput, { PhoneValidationError } from './internal/phone-number-input';
3
- export declare class InstantLinkMaxRetryError extends AuthError {
4
- constructor(message?: string, code?: number);
5
- }
6
2
  export interface InstantLinkStartStep {
7
3
  execute: (phoneNumberNeeded: boolean, instantLinkError?: PhoneValidationError) => Promise<PhoneNumberInput | null>;
8
4
  }
@@ -12,7 +8,7 @@ export declare enum InstantLinkResultType {
12
8
  OnMobileNumberChange = 1
13
9
  }
14
10
  export interface InstantLinkRetryStep {
15
- execute: (instantLinkError?: InstantLinkMaxRetryError) => Promise<InstantLinkResultType>;
11
+ execute: () => Promise<InstantLinkResultType>;
16
12
  }
17
- export type InstantLinkRetryStepFn = (instantLinkError?: InstantLinkMaxRetryError) => Promise<InstantLinkResultType>;
13
+ export type InstantLinkRetryStepFn = () => Promise<InstantLinkResultType>;
18
14
  export type InstantLinkStartInput = PhoneNumberInput;
@@ -1,16 +1,6 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.InstantLinkResultType = exports.InstantLinkMaxRetryError = void 0;
7
- const auth_error_1 = __importDefault(require("./internal/auth-error"));
8
- class InstantLinkMaxRetryError extends auth_error_1.default {
9
- constructor(message, code) {
10
- super(message, code);
11
- }
12
- }
13
- exports.InstantLinkMaxRetryError = InstantLinkMaxRetryError;
3
+ exports.InstantLinkResultType = void 0;
14
4
  var InstantLinkResultType;
15
5
  (function (InstantLinkResultType) {
16
6
  InstantLinkResultType[InstantLinkResultType["OnResend"] = 0] = "OnResend";
@@ -1,6 +1,6 @@
1
1
  import { MobileAuthImplementation } from '../authenticator-builder';
2
2
  import { AuthResponseStatus } from './auth-response-status';
3
- export type AuthRequest = V1ClientDeviceFido2RegisterStart | V1ClientDeviceFido2RegisterFinish | V1ClientDeviceFido2VerifyStart | V1ClientDeviceFido2VerifyFinish | V1ClientDevicePassiveRegister | V1ClientDevicePassiveVerify | V1ClientUserResponse | V1ClientAnyError | V1ClientChallenge | V1ClientMobileInstantLinkStart | V1ClientMobileInstantStart | V1ClientMobileInstantFinish | V1ClientOtpStart | V1ClientOtpFinish;
3
+ export type AuthRequest = V1ClientDeviceFido2RegisterStart | V1ClientDeviceFido2RegisterFinish | V1ClientDeviceFido2VerifyStart | V1ClientDeviceFido2VerifyFinish | V1ClientDevicePassiveRegister | V1ClientDevicePassiveVerify | V1ClientUserResponse | V1ClientAnyError | V1ClientChallenge | V1ClientMobileInstantLinkStart | V1ClientMobileInstantStart | V1ClientMobileInstantFinish | V1ClientOtpStart | V1ClientOtpFinish | V1ClientPpbFinish;
4
4
  export type AuthRegistration = PassiveRegistration | Fido2Registration;
5
5
  export interface PublicKey {
6
6
  id: string;
@@ -33,7 +33,6 @@ export interface V1ClientDeviceFido2RegisterFinish {
33
33
  deviceName: string;
34
34
  deviceCapabilities: string[];
35
35
  registrations: AuthRegistration[];
36
- signals?: Signals;
37
36
  }
38
37
  export interface V1ClientDeviceFido2VerifyStart {
39
38
  deviceId: string;
@@ -52,7 +51,6 @@ export interface WebAuthnAssertion {
52
51
  }
53
52
  export interface V1ClientDeviceFido2VerifyFinish {
54
53
  webAuthnAssertion: WebAuthnAssertion;
55
- signals?: Signals;
56
54
  }
57
55
  export interface V1ClientDevicePassiveRegister {
58
56
  deviceName: string;
@@ -100,3 +98,7 @@ export interface Signal {
100
98
  results?: string;
101
99
  error?: string;
102
100
  }
101
+ export interface V1ClientPpbFinish {
102
+ requestId: string;
103
+ operationId: string;
104
+ }
@@ -1,66 +1,62 @@
1
1
  import AuthMessage from './auth-message';
2
2
  export default interface AuthResponse {
3
3
  next: string;
4
+ data?: ResponseData;
4
5
  error?: AuthFailure;
5
6
  refreshDeviceTrust?: boolean;
6
7
  }
8
+ export interface ResponseData {
9
+ }
7
10
  export interface AuthFailure {
8
11
  message: string;
9
12
  code: number;
10
13
  }
14
+ export type RegisterStartAuthResponse = AuthResponse;
15
+ export type RegisterFinishAuthResponse = AuthResponse;
16
+ export type DeviceRegisterAuthResponse = AuthResponse;
17
+ export type VerifyStartAuthResponse = AuthResponse;
18
+ export type VerifyFinishAuthResponse = AuthResponse;
19
+ export type MobileStartAuthResponse = AuthResponse;
20
+ export type OtpStartResponse = AuthResponse;
21
+ export type OtpFinishResponse = AuthResponse;
22
+ export type InstantLinkStartResponse = AuthResponse;
23
+ export type PpbStartResponse = AuthResponse;
24
+ export type PpbFinishResponse = AuthResponse;
11
25
  export interface RegisterStartAuthResponseData {
12
26
  credCreateOptions?: PublicKeyCredentialCreationOptions;
13
27
  credRequestOptions?: PublicKeyCredentialRequestOptions;
14
28
  }
15
- export interface RegisterStartAuthResponse extends AuthResponse {
16
- data: RegisterStartAuthResponseData;
17
- }
18
- export interface RegisterFinishAuthResponseData {
29
+ export interface RegisterFinishAuthResponseData extends ResponseData {
19
30
  deviceId: string;
20
31
  passkey: boolean;
21
32
  scanMessage?: AuthMessage;
22
33
  }
23
- export interface RegisterFinishAuthResponse extends AuthResponse {
24
- data: RegisterFinishAuthResponseData;
25
- }
26
- export type DeviceRegisterAuthResponse = RegisterFinishAuthResponse;
27
34
  export interface VerifyStartAuthResponseData {
28
35
  credRequestOptions: PublicKeyCredentialRequestOptions;
29
36
  }
30
- export interface VerifyStartAuthResponse extends AuthResponse {
31
- data: VerifyStartAuthResponseData;
32
- }
33
- export interface VerifyFinishAuthResponseData {
37
+ export interface VerifyFinishAuthResponseData extends ResponseData {
34
38
  scanMessage?: AuthMessage;
35
39
  deviceId?: string;
36
40
  passkey?: boolean;
37
41
  }
38
- export interface VerifyFinishAuthResponse extends AuthResponse {
39
- data?: VerifyFinishAuthResponseData;
40
- }
41
42
  export interface ChallengeResponse extends AuthResponse {
42
43
  deviceId?: string;
43
44
  challenge?: string;
44
45
  ttl?: number;
45
46
  receivedAt?: number;
46
47
  }
47
- export interface MobileStartAuthResponseData {
48
+ export interface MobileStartAuthResponseData extends ResponseData {
48
49
  redirectUrl?: string;
49
50
  }
50
- export interface MobileStartAuthResponse extends AuthResponse {
51
- data?: MobileStartAuthResponseData;
52
- }
53
- export interface OtpStartResponse extends AuthResponse {
54
- data?: OtpResponseData;
55
- }
56
- export interface OtpFinishResponse extends AuthResponse {
57
- data?: OtpResponseData;
58
- }
59
51
  export interface OtpResponseData {
60
52
  code?: number;
61
53
  message?: string;
62
54
  }
63
- export interface InstantLinkStartResponse extends AuthResponse {
64
- data?: InstantLinkResponseData;
65
- }
66
55
  export type InstantLinkResponseData = OtpResponseData;
56
+ export interface PpbOperation {
57
+ operationId: string;
58
+ oneTimeSecret: string;
59
+ }
60
+ export interface PpbResponseData extends ResponseData {
61
+ ppb?: PpbOperation;
62
+ }
@@ -1,7 +1,7 @@
1
1
  /// <reference types="webappsec-credential-management" />
2
2
  import AuthMessage from './auth-message';
3
3
  import { AuthRequest, Signal } from './auth-request';
4
- import AuthResponse from './auth-response';
4
+ import AuthResponse, { ResponseData } from './auth-response';
5
5
  import AuthTokenClaims, { UserVerificationLevel } from './auth-token-claims';
6
6
  import { DeviceRegistration } from './device-auth';
7
7
  import Platform, { AuthSessionIntegration, MessageChannel, RequestSigner } from './platform';
@@ -16,6 +16,7 @@ export default class AuthSession implements AuthSessionIntegration {
16
16
  readonly channels: Set<MessageChannel>;
17
17
  private readonly log;
18
18
  lastStep?: string;
19
+ lastData?: ResponseData;
19
20
  credential?: CredentialType;
20
21
  authMessage?: AuthMessage;
21
22
  uvLevel?: UserVerificationLevel;
@@ -32,7 +33,11 @@ export default class AuthSession implements AuthSessionIntegration {
32
33
  closeAllMessageChannels(): void;
33
34
  getDeviceRegistration(): Promise<DeviceRegistration | null>;
34
35
  embedFpResultToDeviceRegistration(registration: DeviceRegistration): Promise<DeviceRegistration>;
36
+ private getCurrentTimestampInSeconds;
37
+ markNewFptts(ts?: number): void;
38
+ resetFptts(): void;
35
39
  getFingerprintData(): Promise<Signal | undefined>;
36
40
  shouldCollectFP(): boolean;
41
+ shouldRefreshFpSignal(currentTimestamp: number): boolean;
37
42
  private parseJwt;
38
43
  }
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const logger_1 = require("../common/logger");
7
7
  const version_1 = require("../version");
8
+ const auth_error_1 = __importDefault(require("./auth-error"));
8
9
  const auth_token_claims_1 = require("./auth-token-claims");
9
10
  const error_code_1 = __importDefault(require("./error-code"));
10
11
  const web_socket_close_reasons_1 = require("./web-socket-close-reasons");
@@ -84,6 +85,7 @@ class AuthSession {
84
85
  this.platform.deviceAuth.reset();
85
86
  }
86
87
  }
88
+ this.lastData = response.data;
87
89
  resolve(response);
88
90
  })
89
91
  .catch(reject);
@@ -164,8 +166,7 @@ class AuthSession {
164
166
  onClose(reason, code);
165
167
  });
166
168
  channel.addEventListener('error', (event) => {
167
- this.log.debug('Message channel encountered an error');
168
- this.log.debug(event);
169
+ this.log.debug('Message channel encountered an error', event);
169
170
  });
170
171
  channel.addEventListener('message', (event) => {
171
172
  this.log.trace('Message channel received a message');
@@ -227,17 +228,28 @@ class AuthSession {
227
228
  resolve(registration);
228
229
  })
229
230
  .catch((error) => {
230
- const errorMsg = `Unexpected error happened during Fingerprint data collection: ${error.toString}`;
231
- this.log.warn(errorMsg);
231
+ const errorMsg = `Unexpected error happened during Fingerprint data collection: ${auth_error_1.default.extractMessage(error)}`;
232
+ this.log.warn(error);
232
233
  registration.setFpSignal({ error: errorMsg });
233
234
  });
234
235
  });
235
236
  }
237
+ getCurrentTimestampInSeconds() {
238
+ const currentTimestampMs = Date.now();
239
+ const currentTimestampSeconds = Math.floor(currentTimestampMs / 1000);
240
+ return currentTimestampSeconds;
241
+ }
242
+ markNewFptts(ts) {
243
+ this.settings.fingerPrintTimestamp = ts ? ts : this.getCurrentTimestampInSeconds();
244
+ }
245
+ resetFptts() {
246
+ this.settings.fingerPrintTimestamp = null;
247
+ }
236
248
  getFingerprintData() {
237
249
  return new Promise((resolve) => {
238
250
  var fpPromise = this.platform.getFpPromise();
239
251
  if (!this.shouldCollectFP()) {
240
- this.log.debug('Fingerprint is not enabled from AuthToken');
252
+ this.log.trace('Fingerprint is not enabled from AuthToken');
241
253
  resolve(undefined);
242
254
  }
243
255
  else if (!fpPromise) {
@@ -245,7 +257,12 @@ class AuthSession {
245
257
  this.log.warn(msg);
246
258
  resolve({ error: msg });
247
259
  }
260
+ else if (!this.shouldRefreshFpSignal(this.getCurrentTimestampInSeconds())) {
261
+ this.log.trace('Existing FP signal is not yet expired, skip new collection');
262
+ resolve(undefined);
263
+ }
248
264
  else {
265
+ this.log.trace('Collect new FP signal');
249
266
  fpPromise
250
267
  .then((fp) => fp.get())
251
268
  .then((result) => {
@@ -260,8 +277,8 @@ class AuthSession {
260
277
  }
261
278
  })
262
279
  .catch((error) => {
263
- const msg = `Error in collecting Fingerprint data: ${error.toString}`;
264
- this.log.warn(msg);
280
+ const msg = `Error in collecting Fingerprint data: ${auth_error_1.default.extractMessage(error)}`;
281
+ this.log.warn(error);
265
282
  resolve({ error: msg });
266
283
  });
267
284
  }
@@ -274,6 +291,16 @@ class AuthSession {
274
291
  }
275
292
  return false;
276
293
  }
294
+ shouldRefreshFpSignal(currentTimestamp) {
295
+ var _a, _b, _c, _d;
296
+ if (!this.settings.deviceId || !this.settings.fingerPrintTimestamp) {
297
+ this.resetFptts();
298
+ return true;
299
+ }
300
+ const refreshRate = (_d = (_c = (_b = (_a = this.claims) === null || _a === void 0 ? void 0 : _a.auth.subs.dev) === null || _b === void 0 ? void 0 : _b.sgnls) === null || _c === void 0 ? void 0 : _c.fptrr) !== null && _d !== void 0 ? _d : 0;
301
+ const interval = currentTimestamp - this.settings.fingerPrintTimestamp;
302
+ return interval >= refreshRate;
303
+ }
277
304
  parseJwt(token) {
278
305
  return JSON.parse(atob(token.split('.')[1]));
279
306
  }
@@ -9,6 +9,8 @@ export interface PassiveAuthenticator {
9
9
  }
10
10
  export interface InstantAuthenticator {
11
11
  }
12
+ export interface PresentAuthenticator {
13
+ }
12
14
  export interface InstantLinkAuthenticator {
13
15
  mnp: boolean;
14
16
  amnrp?: boolean;
@@ -21,27 +23,44 @@ export interface UniversalAuthenticator {
21
23
  endp: string;
22
24
  ftu: string;
23
25
  }
24
- export interface Authenticators {
26
+ export interface PpbAuthenticator {
27
+ endp: string;
28
+ }
29
+ export interface DeviceAuthenticators {
30
+ pasv?: PassiveAuthenticator;
31
+ unvsl?: UniversalAuthenticator;
32
+ }
33
+ export interface MobileAuthenticators {
25
34
  pasv?: PassiveAuthenticator;
26
35
  inst?: InstantAuthenticator;
27
36
  inln?: InstantLinkAuthenticator;
28
37
  otp?: OtpAuthenticator;
29
38
  unvsl?: UniversalAuthenticator;
30
39
  }
40
+ export interface UserAuthenticators {
41
+ pasv?: PassiveAuthenticator;
42
+ prst?: PresentAuthenticator;
43
+ ppb?: PpbAuthenticator;
44
+ }
31
45
  export interface Signals {
32
46
  fpt?: boolean;
47
+ fptrr?: number;
33
48
  dwn?: boolean;
34
49
  }
35
50
  export interface DeviceAuthSubjectClaim {
36
- auths: Authenticators;
51
+ auths: DeviceAuthenticators;
37
52
  sgnls?: Signals;
38
53
  }
39
54
  export interface MobileAuthSubjectClaim {
40
- auths: Authenticators;
55
+ auths: MobileAuthenticators;
56
+ }
57
+ export interface UserAuthSubjectClaim {
58
+ auths: UserAuthenticators;
41
59
  }
42
60
  export interface AuthSubjectsClaim {
43
61
  dev?: DeviceAuthSubjectClaim;
44
62
  mob?: MobileAuthSubjectClaim;
63
+ usr?: UserAuthSubjectClaim;
45
64
  }
46
65
  export interface AuthClaim {
47
66
  id: string;
@@ -23,11 +23,9 @@ class DevicePassiveRegisterStep {
23
23
  .getDeviceRegistration()
24
24
  .then((devRegistration) => {
25
25
  if (devRegistration) {
26
- session.embedFpResultToDeviceRegistration(devRegistration).then((devRegistration) => {
27
- this.finishRegistration(session, [this.getFido2Registration(session)], devRegistration.getSignals())
28
- .then(resolve)
29
- .catch(reject);
30
- });
26
+ this.finishRegistration(session, [this.getFido2Registration(session)])
27
+ .then(resolve)
28
+ .catch(reject);
31
29
  }
32
30
  else {
33
31
  session.platform.deviceAuth
@@ -35,11 +33,13 @@ class DevicePassiveRegisterStep {
35
33
  namespace: session.namespace,
36
34
  endpoint: session.backendOrigin,
37
35
  })
38
- .then((devRegistration) => session.embedFpResultToDeviceRegistration(devRegistration))
39
36
  .then((devRegistration) => {
40
37
  devRegistration
41
38
  .getAuthRegistration(session.challenge)
42
- .then((authRegistration) => this.finishRegistration(session, [this.getFido2Registration(session), authRegistration], devRegistration.getSignals()))
39
+ .then((authRegistration) => this.finishRegistration(session, [
40
+ this.getFido2Registration(session),
41
+ authRegistration,
42
+ ]))
43
43
  .then((next) => {
44
44
  devRegistration.deviceId = session.settings.deviceId;
45
45
  session.platform.deviceAuth
@@ -61,14 +61,13 @@ class DevicePassiveRegisterStep {
61
61
  const assertion = credential.response;
62
62
  return assertion && 'authenticatorData' in assertion && 'signature' in assertion;
63
63
  }
64
- finishRegistration(session, registrations, signals) {
64
+ finishRegistration(session, registrations) {
65
65
  return new Promise((resolve, reject) => {
66
66
  session
67
67
  .fetchFromBackend('/v1/client/device/fido2/register/finish', {
68
68
  deviceName: session.platform.getPlatformName(),
69
69
  deviceCapabilities: session.platform.getDeviceCapabilities(),
70
70
  registrations: registrations,
71
- signals: signals,
72
71
  })
73
72
  .then((response) => {
74
73
  if (response.error) {
@@ -70,23 +70,26 @@ class DevicePassiveSilentStep {
70
70
  signals: registration.getSignals(),
71
71
  })
72
72
  .then((response) => {
73
+ var _a;
73
74
  if (response.error) {
74
75
  reject(new auth_error_1.default(response.error.message, response.error.code, response.next, false));
75
76
  }
76
77
  else {
77
- const deviceRegisterAuthResp = response;
78
- const deviceId = deviceRegisterAuthResp.data.deviceId;
78
+ if ((_a = registration.getSignals().fingerprint) === null || _a === void 0 ? void 0 : _a.results) {
79
+ session.markNewFptts();
80
+ }
81
+ const data = response.data;
82
+ const deviceId = data === null || data === void 0 ? void 0 : data.deviceId;
79
83
  if (!deviceId) {
80
84
  reject(new auth_error_1.default('Failed to register device, returned deviceId is null or empty', 0, response.next));
81
85
  }
82
86
  session.settings.deviceId = deviceId;
83
- if (deviceRegisterAuthResp.data.passkey != null) {
84
- session.settings.fidoPasskeyRegistered = deviceRegisterAuthResp.data.passkey;
87
+ if (data.passkey != null) {
88
+ session.settings.fidoPasskeyRegistered = data.passkey;
85
89
  }
86
90
  registration.deviceId = deviceId;
87
91
  this.log.debug('Device ID: ' + deviceId);
88
- const data = response.data;
89
- if (data && data.scanMessage) {
92
+ if (data.scanMessage) {
90
93
  session.authMessage = data.scanMessage;
91
94
  }
92
95
  session.platform.deviceAuth
@@ -113,10 +116,14 @@ class DevicePassiveSilentStep {
113
116
  signals: registration.getSignals(),
114
117
  })
115
118
  .then((response) => {
119
+ var _a;
116
120
  if (response.error) {
117
121
  reject(new auth_error_1.default(response.error.message, response.error.code, response.next, false));
118
122
  }
119
123
  else {
124
+ if ((_a = registration.getSignals().fingerprint) === null || _a === void 0 ? void 0 : _a.results) {
125
+ session.markNewFptts();
126
+ }
120
127
  resolve(response.next);
121
128
  }
122
129
  })
@@ -30,13 +30,17 @@ class DevicePassiveActions extends auth_status_actions_1.AuthStatusActions {
30
30
  signals: signals,
31
31
  })
32
32
  .then((response) => {
33
- var _a, _b;
33
+ var _a;
34
34
  if (response.error) {
35
35
  reject(new auth_error_1.default(response.error.message, response.error.code, response.next, false));
36
36
  }
37
37
  else {
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;
38
+ if ((_a = signals === null || signals === void 0 ? void 0 : signals.fingerprint) === null || _a === void 0 ? void 0 : _a.results) {
39
+ session.markNewFptts();
40
+ }
41
+ const data = response.data;
42
+ const creationOptions = data === null || data === void 0 ? void 0 : data.credCreateOptions;
43
+ const requestOptions = data === null || data === void 0 ? void 0 : data.credRequestOptions;
40
44
  if (creationOptions) {
41
45
  this.createCredentials(session, displayName, creationOptions, response)
42
46
  .then(resolve)
@@ -67,7 +71,8 @@ class DevicePassiveActions extends auth_status_actions_1.AuthStatusActions {
67
71
  reject(new auth_error_1.default(response.error.message, response.error.code, response.next, false));
68
72
  }
69
73
  else {
70
- const options = response.data.credRequestOptions;
74
+ const data = response.data;
75
+ const options = data === null || data === void 0 ? void 0 : data.credRequestOptions;
71
76
  this.getCredentials(session, options, response).then(resolve).catch(reject);
72
77
  }
73
78
  })
@@ -141,7 +146,7 @@ class DevicePassiveActions extends auth_status_actions_1.AuthStatusActions {
141
146
  parseCredRequestOptions(response, session) {
142
147
  return new Promise((resolve, reject) => {
143
148
  const data = response.data;
144
- if (data.credRequestOptions) {
149
+ if (data === null || data === void 0 ? void 0 : data.credRequestOptions) {
145
150
  const requestOptions = data.credRequestOptions;
146
151
  this.getCredentials(session, requestOptions, response).then(resolve).catch(reject);
147
152
  }
@@ -19,25 +19,7 @@ class DevicePassiveStepupStep extends device_passive_step_1.DevicePassiveActions
19
19
  return Promise.reject(new Error('FIDO2 Passkey is already registered'));
20
20
  }
21
21
  return new Promise((resolve, reject) => {
22
- session
23
- .getFingerprintData()
24
- .then((signal) => {
25
- const signals = {
26
- fingerprint: signal,
27
- };
28
- this.register(session, signals).then(resolve).catch(reject);
29
- })
30
- .catch((error) => {
31
- const errorMsg = `Unexpected error happened during Fingerprint data collection: ${error.message}`;
32
- this.log.warn(errorMsg);
33
- this.log.warn(error);
34
- const signals = {
35
- fingerprint: {
36
- error: errorMsg,
37
- },
38
- };
39
- this.register(session, signals).then(resolve).catch(reject);
40
- });
22
+ this.register(session).then(resolve).catch(reject);
41
23
  });
42
24
  }
43
25
  }