@zeniai/client-epic-state 4.18.52 → 4.18.53

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.
@@ -1,2 +1,2 @@
1
- export declare const toAnimationsFileName: (v: string) => "AiAgent" | "AiIconEntry" | "AiIconExit" | "AiIconLoop" | "AiStar" | "AiStarPlain" | "AIPoweredInvoiceDark" | "AIPoweredInvoiceLight" | "Angry" | "Confetti" | "ConfettiSuccess" | "DashboardSidebarBackground" | "DashboardSidebarBottom" | "DashboardSidebarBottomHalloween" | "DashboardSidebarBottomThanksgiving" | "DashboardSidebarLogoDark" | "DashboardSidebarLogoLight" | "DashboardSidebarTopHalloween" | "DashboardSidebarTopThanksgiving" | "FastestWayDark" | "FastestWayLight" | "FinanceTeamDark" | "FinanceTeamLight" | "Happy" | "MoneyTransferSuccess" | "MultiLevelApprovalDark" | "MultiLevelApprovalLight" | "NotHappy" | "ReceiptDark" | "ReceiptLight" | "ReimburseDark" | "ReimburseLight" | "RewardsDark" | "RewardsDarkHover" | "RewardsLight" | "RewardsLightHover" | "Secure" | "Success" | "VeryHappy" | "ZeniAssist";
1
+ export declare const toAnimationsFileName: (v: string) => "AiAgent" | "AiIconEntry" | "AiIconExit" | "AiIconLoop" | "AiStar" | "AiStarIcon" | "AiStarPlain" | "AIPoweredInvoiceDark" | "AIPoweredInvoiceLight" | "Angry" | "Confetti" | "ConfettiSuccess" | "DashboardChristmasSnow" | "DashboardSidebarBackground" | "DashboardSidebarBottom" | "DashboardSidebarBottomChristmas" | "DashboardSidebarBottomHalloween" | "DashboardSidebarBottomThanksgiving" | "DashboardSidebarLogoDark" | "DashboardSidebarLogoLight" | "DashboardSidebarTopChristmas" | "DashboardSidebarTopHalloween" | "DashboardSidebarTopThanksgiving" | "FastestWayDark" | "FastestWayLight" | "FinanceTeamDark" | "FinanceTeamLight" | "Happy" | "MoneyTransferSuccess" | "MultiLevelApprovalDark" | "MultiLevelApprovalLight" | "NotHappy" | "ReceiptDark" | "ReceiptLight" | "ReimburseDark" | "ReimburseLight" | "RewardsDark" | "RewardsDarkHover" | "RewardsLight" | "RewardsLightHover" | "Secure" | "Success" | "VeryHappy" | "ZeniAssist";
2
2
  export type AnimationFileName = ReturnType<typeof toAnimationsFileName>;
@@ -8,18 +8,22 @@ const ALL_ANIMATIONS_FILE_NAMES = [
8
8
  'AiIconExit',
9
9
  'AiIconLoop',
10
10
  'AiStar',
11
+ 'AiStarIcon',
11
12
  'AiStarPlain',
12
13
  'AIPoweredInvoiceDark',
13
14
  'AIPoweredInvoiceLight',
14
15
  'Angry',
15
16
  'Confetti',
16
17
  'ConfettiSuccess',
18
+ 'DashboardChristmasSnow',
17
19
  'DashboardSidebarBackground',
18
20
  'DashboardSidebarBottom',
21
+ 'DashboardSidebarBottomChristmas',
19
22
  'DashboardSidebarBottomHalloween',
20
23
  'DashboardSidebarBottomThanksgiving',
21
24
  'DashboardSidebarLogoDark',
22
25
  'DashboardSidebarLogoLight',
26
+ 'DashboardSidebarTopChristmas',
23
27
  'DashboardSidebarTopHalloween',
24
28
  'DashboardSidebarTopThanksgiving',
25
29
  'FastestWayDark',
@@ -0,0 +1,52 @@
1
+ /**
2
+ * System information that can be collected from the client side
3
+ * when sending email magic link requests
4
+ */
5
+ export interface SystemInfo {
6
+ browser: {
7
+ name: string;
8
+ userAgent: string;
9
+ version: string;
10
+ };
11
+ device: {
12
+ isDesktop: boolean;
13
+ isMobile: boolean;
14
+ isTablet: boolean;
15
+ type: 'desktop' | 'mobile' | 'tablet' | 'unknown';
16
+ };
17
+ language: {
18
+ all: readonly string[];
19
+ primary: string;
20
+ };
21
+ metadata: {
22
+ referrer: string;
23
+ timestamp: string;
24
+ url: string;
25
+ };
26
+ os: {
27
+ name: string;
28
+ platform: string;
29
+ version: string;
30
+ };
31
+ screen: {
32
+ colorDepth: number;
33
+ height: number;
34
+ pixelRatio: number;
35
+ width: number;
36
+ };
37
+ timezone: {
38
+ name: string;
39
+ offset: number;
40
+ };
41
+ network?: {
42
+ connectionType?: string;
43
+ downlink?: number;
44
+ effectiveType?: string;
45
+ rtt?: number;
46
+ };
47
+ }
48
+ /**
49
+ * Collects comprehensive system information from the client
50
+ * @returns SystemInfo object with all available system details
51
+ */
52
+ export declare function collectSystemInfo(): SystemInfo;
@@ -0,0 +1,242 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.collectSystemInfo = collectSystemInfo;
4
+ /**
5
+ * Array of browser detection configurations, ordered by specificity
6
+ * (more specific browsers should be checked first)
7
+ */
8
+ const browserConfigs = [
9
+ {
10
+ name: 'Chrome',
11
+ versionRegex: /Chrome\/(\d+\.\d+)/,
12
+ test: (userAgent) => userAgent.includes('Chrome') && !userAgent.includes('Edg'),
13
+ },
14
+ {
15
+ name: 'Firefox',
16
+ versionRegex: /Firefox\/(\d+\.\d+)/,
17
+ test: (userAgent) => userAgent.includes('Firefox'),
18
+ },
19
+ {
20
+ name: 'Safari',
21
+ versionRegex: /Version\/(\d+\.\d+)/,
22
+ test: (userAgent) => userAgent.includes('Safari') && !userAgent.includes('Chrome'),
23
+ },
24
+ {
25
+ name: 'Edge',
26
+ versionRegex: /Edg\/(\d+\.\d+)/,
27
+ test: (userAgent) => userAgent.includes('Edg'),
28
+ },
29
+ {
30
+ name: 'Internet Explorer',
31
+ versionRegex: /(?:MSIE |rv:)(\d+\.\d+)/,
32
+ test: (userAgent) => userAgent.includes('Trident') || userAgent.includes('MSIE'),
33
+ },
34
+ ];
35
+ /**
36
+ * Detects browser name and version from user agent
37
+ */
38
+ function getBrowserInfo() {
39
+ const userAgent = navigator.userAgent;
40
+ for (const config of browserConfigs) {
41
+ if (config.test(userAgent)) {
42
+ const match = userAgent.match(config.versionRegex);
43
+ return {
44
+ name: config.name,
45
+ version: match ? match[1] : 'unknown',
46
+ userAgent,
47
+ };
48
+ }
49
+ }
50
+ return {
51
+ name: 'Unknown',
52
+ version: 'unknown',
53
+ userAgent,
54
+ };
55
+ }
56
+ /**
57
+ * Windows NT version to readable version mapping
58
+ */
59
+ const windowsVersionMap = {
60
+ '10.0': '10',
61
+ '6.3': '8.1',
62
+ '6.2': '8',
63
+ '6.1': '7',
64
+ '6.0': 'Vista',
65
+ '5.1': 'XP',
66
+ '5.0': '2000',
67
+ };
68
+ /**
69
+ * Array of OS detection configurations, ordered by specificity
70
+ * (more specific OS should be checked first)
71
+ */
72
+ const osConfigs = [
73
+ {
74
+ name: 'Windows',
75
+ versionRegex: /Windows NT (\d+\.\d+)/,
76
+ extractVersion: (match) => {
77
+ if (!match) {
78
+ return 'unknown';
79
+ }
80
+ const ntVersion = match[1];
81
+ return windowsVersionMap[ntVersion] || ntVersion;
82
+ },
83
+ test: (userAgent) => userAgent.includes('Windows'),
84
+ },
85
+ {
86
+ name: 'macOS',
87
+ versionRegex: /Mac OS X (\d+[._]\d+)/,
88
+ extractVersion: (match) => {
89
+ return match ? match[1].replace(/_/g, '.') : 'unknown';
90
+ },
91
+ test: (userAgent) => userAgent.includes('Mac OS X'),
92
+ },
93
+ {
94
+ name: 'iOS',
95
+ versionRegex: /OS (\d+[._]\d+)/,
96
+ extractVersion: (match) => {
97
+ return match ? match[1].replace(/_/g, '.') : 'unknown';
98
+ },
99
+ test: (userAgent) => userAgent.includes('iPhone') || userAgent.includes('iPad'),
100
+ },
101
+ {
102
+ name: 'Android',
103
+ versionRegex: /Android (\d+\.\d+)/,
104
+ extractVersion: (match) => {
105
+ return match ? match[1] : 'unknown';
106
+ },
107
+ test: (userAgent) => userAgent.includes('Android'),
108
+ },
109
+ {
110
+ name: 'Linux',
111
+ versionRegex: null,
112
+ extractVersion: () => 'unknown',
113
+ test: (userAgent) => userAgent.includes('Linux'),
114
+ },
115
+ ];
116
+ /**
117
+ * Detects operating system from user agent
118
+ */
119
+ function getOSInfo() {
120
+ const userAgent = navigator.userAgent;
121
+ const platform = navigator.platform;
122
+ for (const config of osConfigs) {
123
+ if (config.test(userAgent)) {
124
+ const match = config.versionRegex
125
+ ? userAgent.match(config.versionRegex)
126
+ : null;
127
+ return {
128
+ name: config.name,
129
+ version: config.extractVersion(match),
130
+ platform,
131
+ };
132
+ }
133
+ }
134
+ return {
135
+ name: 'Unknown',
136
+ version: 'unknown',
137
+ platform,
138
+ };
139
+ }
140
+ /**
141
+ * Detects device type and characteristics
142
+ */
143
+ function getDeviceInfo() {
144
+ const userAgent = navigator.userAgent;
145
+ const isTablet = /iPad|Android(?!.*Mobile)/i.test(userAgent);
146
+ const isMobile = /Android.*Mobile|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent);
147
+ const isDesktop = !isMobile && !isTablet;
148
+ let type = 'unknown';
149
+ if (isMobile) {
150
+ type = 'mobile';
151
+ }
152
+ else if (isTablet) {
153
+ type = 'tablet';
154
+ }
155
+ else if (isDesktop) {
156
+ type = 'desktop';
157
+ }
158
+ return {
159
+ type,
160
+ isMobile,
161
+ isTablet,
162
+ isDesktop,
163
+ };
164
+ }
165
+ /**
166
+ * Gets screen information
167
+ */
168
+ function getScreenInfo() {
169
+ return {
170
+ width: screen.width,
171
+ height: screen.height,
172
+ colorDepth: screen.colorDepth,
173
+ pixelRatio: window.devicePixelRatio || 1,
174
+ };
175
+ }
176
+ /**
177
+ * Gets network information if available
178
+ */
179
+ function getNetworkInfo() {
180
+ // Cast navigator to our extended interface to access network connection properties
181
+ const nav = navigator;
182
+ const connection = nav.connection || nav.mozConnection || nav.webkitConnection;
183
+ if (connection) {
184
+ return {
185
+ connectionType: connection.type,
186
+ effectiveType: connection.effectiveType,
187
+ downlink: connection.downlink,
188
+ rtt: connection.rtt,
189
+ };
190
+ }
191
+ return undefined;
192
+ }
193
+ /**
194
+ * Gets timezone information
195
+ */
196
+ function getTimezoneInfo() {
197
+ const now = new Date();
198
+ const offset = -now.getTimezoneOffset() / 60; // Convert to hours
199
+ const name = Intl.DateTimeFormat().resolvedOptions().timeZone;
200
+ return {
201
+ offset,
202
+ name,
203
+ };
204
+ }
205
+ /**
206
+ * Gets language information
207
+ */
208
+ function getLanguageInfo() {
209
+ const languages = navigator.languages != null
210
+ ? Array.from(navigator.languages)
211
+ : [navigator.language];
212
+ return {
213
+ primary: navigator.language,
214
+ all: languages,
215
+ };
216
+ }
217
+ /**
218
+ * Gets additional metadata
219
+ */
220
+ function getMetadata() {
221
+ return {
222
+ timestamp: new Date().toISOString(),
223
+ url: window.location.href,
224
+ referrer: document.referrer,
225
+ };
226
+ }
227
+ /**
228
+ * Collects comprehensive system information from the client
229
+ * @returns SystemInfo object with all available system details
230
+ */
231
+ function collectSystemInfo() {
232
+ return {
233
+ browser: getBrowserInfo(),
234
+ os: getOSInfo(),
235
+ device: getDeviceInfo(),
236
+ screen: getScreenInfo(),
237
+ network: getNetworkInfo(),
238
+ timezone: getTimezoneInfo(),
239
+ language: getLanguageInfo(),
240
+ metadata: getMetadata(),
241
+ };
242
+ }
@@ -212,6 +212,7 @@ interface CompanyFeaturesActivationInfoPayload {
212
212
  is_deposit_accounts_feature_enabled: boolean;
213
213
  is_feature_vendor_listing_enabled: boolean;
214
214
  is_reimbursement_feature_enabled: boolean;
215
+ is_same_day_ach_enabled: boolean;
215
216
  }
216
217
  export declare const toCompanyTreasuryInfo: (payload: CompanyTreasuryInfoDataPayload) => CompanyTreasuryInfo;
217
218
  export declare const toOnboardingInfo: (onboardingInfoPayload?: OnboardingInfoPayload) => OnboardingInfo | undefined;
@@ -120,6 +120,7 @@ const toCompanyFeaturesActivationInfo = (payload) => ({
120
120
  isReimbursementFeatureEnabled: payload.is_reimbursement_feature_enabled,
121
121
  connectedAccountProvider: payload.connected_account_provider,
122
122
  isFeatureVendorListingEnabled: payload.is_feature_vendor_listing_enabled,
123
+ isSameDayAchFeatureEnabled: payload.is_same_day_ach_enabled,
123
124
  });
124
125
  const toCompanyBillPayInfo = (payload) => {
125
126
  var _a, _b, _c;
@@ -257,6 +257,7 @@ export interface CompanyFeaturesActivationInfo {
257
257
  isBillPayFeatureEnabled: boolean;
258
258
  isFeatureVendorListingEnabled: boolean;
259
259
  isReimbursementFeatureEnabled: boolean;
260
+ isSameDayAchFeatureEnabled: boolean;
260
261
  }
261
262
  export interface CompanyMileageConfigInfo {
262
263
  defaultMileageUnitAmount: number;
@@ -19,6 +19,13 @@ export declare const doMagicLinkSignInEpic: (actions$: ActionsObservable<ActionT
19
19
  } | {
20
20
  payload: import("../../../responsePayload").ZeniAPIStatus<Record<string, unknown>>;
21
21
  type: "tenant/magicLinkSignInFailure";
22
+ } | {
23
+ payload: {
24
+ otpChallenge: string;
25
+ userEmail: string;
26
+ twoFAPhoneNumber: string;
27
+ };
28
+ type: "tenant/trigger2FA";
22
29
  } | {
23
30
  payload: {
24
31
  userId: string;
@@ -3,24 +3,45 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.doMagicLinkSignInEpic = void 0;
4
4
  const rxjs_1 = require("rxjs");
5
5
  const operators_1 = require("rxjs/operators");
6
+ const systemInfo_1 = require("../../../commonStateTypes/systemInfo");
6
7
  const responsePayload_1 = require("../../../responsePayload");
7
8
  const tenantReducer_1 = require("../tenantReducer");
8
- const toRequestPayload = (token, magicLinkCodeVerifier) => ({
9
- token,
10
- pkce_code_verifier: magicLinkCodeVerifier,
11
- auth_type: 'magic_links',
12
- });
9
+ const toRequestPayload = (token, deviceId, magicLinkCodeVerifier, isOtpResend, email) => {
10
+ const payload = {
11
+ token,
12
+ device_id: deviceId,
13
+ auth_type: 'magic_links',
14
+ device_info: (0, systemInfo_1.collectSystemInfo)(),
15
+ };
16
+ if (magicLinkCodeVerifier != null) {
17
+ payload.pkce_code_verifier = magicLinkCodeVerifier;
18
+ }
19
+ if (isOtpResend === true) {
20
+ payload.is_otp_resend = true;
21
+ }
22
+ if (email != null) {
23
+ payload.user_email = email;
24
+ }
25
+ return payload;
26
+ };
13
27
  const doMagicLinkSignInEpic = (actions$, _, zeniAPI) => actions$.pipe((0, operators_1.filter)(tenantReducer_1.doMagicLinkSignIn.match), (0, operators_1.switchMap)((action) => {
14
- const { token, magicLinkCodeVerifier } = action.payload;
28
+ const { token, deviceId, isOtpResend, email, magicLinkCodeVerifier } = action.payload;
15
29
  return zeniAPI
16
- .postJSON(`${zeniAPI.apiEndPoints.authMicroServiceBaseUrl}/1.0/signin`, toRequestPayload(token, magicLinkCodeVerifier))
30
+ .postJSON(`${zeniAPI.apiEndPoints.authMicroServiceBaseUrl}/1.0/signin`, toRequestPayload(token, deviceId, magicLinkCodeVerifier, isOtpResend, email))
17
31
  .pipe((0, operators_1.concatMap)((response) => {
18
32
  return (0, rxjs_1.from)(response.json()).pipe((0, operators_1.mergeMap)((responseJson) => {
33
+ var _a, _b, _c;
19
34
  const signInResponse = responseJson;
35
+ if (((_a = signInResponse.data) === null || _a === void 0 ? void 0 : _a.otp_challenge) != null &&
36
+ ((_b = signInResponse.data) === null || _b === void 0 ? void 0 : _b.user_email) != null &&
37
+ ((_c = signInResponse.data) === null || _c === void 0 ? void 0 : _c.phone_number) != null) {
38
+ return (0, rxjs_1.of)((0, tenantReducer_1.trigger2FA)(signInResponse.data.otp_challenge, signInResponse.data.user_email, signInResponse.data.phone_number));
39
+ }
20
40
  const sessionId = response.headers.get('zeni-session-id');
21
41
  if (response.ok &&
22
42
  (0, responsePayload_1.isSuccessResponse)(responseJson) &&
23
43
  signInResponse.data != null &&
44
+ signInResponse.data.user != null &&
24
45
  sessionId != null) {
25
46
  return (0, rxjs_1.of)((0, tenantReducer_1.updateLoggedInUser)(signInResponse.data.user, sessionId, 'email'), (0, tenantReducer_1.magicLinkSignInSuccess)(signInResponse.data.user.user_id, sessionId), (0, tenantReducer_1.fetchAllTenants)(signInResponse.data.user.user_id, sessionId));
26
47
  }
@@ -3,16 +3,30 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.sendEmailMagicLinkToUserEpic = void 0;
4
4
  const rxjs_1 = require("rxjs");
5
5
  const operators_1 = require("rxjs/operators");
6
+ const systemInfo_1 = require("../../../commonStateTypes/systemInfo");
6
7
  const snackbarReducer_1 = require("../../../entity/snackbar/snackbarReducer");
7
8
  const responsePayload_1 = require("../../../responsePayload");
8
9
  const tenantReducer_1 = require("../tenantReducer");
9
- const toRequestPayload = (email) => ({
10
- email,
11
- });
10
+ const toRequestPayload = (email, deviceId) => {
11
+ try {
12
+ const systemInfo = (0, systemInfo_1.collectSystemInfo)();
13
+ return {
14
+ email,
15
+ device_id: deviceId,
16
+ device_info: systemInfo,
17
+ };
18
+ }
19
+ catch (_a) {
20
+ return {
21
+ email,
22
+ device_id: deviceId,
23
+ };
24
+ }
25
+ };
12
26
  const sendEmailMagicLinkToUserEpic = (actions$, _, zeniAPI) => actions$.pipe((0, operators_1.filter)(tenantReducer_1.sendEmailMagicLinkToUser.match), (0, operators_1.switchMap)((action) => {
13
- const { email } = action.payload;
27
+ const { email, deviceId } = action.payload;
14
28
  return zeniAPI
15
- .postAndGetJSON(`${zeniAPI.apiEndPoints.authMicroServiceBaseUrl}/1.0/signin/magic-link`, toRequestPayload(email))
29
+ .postAndGetJSON(`${zeniAPI.apiEndPoints.authMicroServiceBaseUrl}/1.0/signin/magic-link`, toRequestPayload(email, deviceId))
16
30
  .pipe((0, operators_1.mergeMap)((response) => {
17
31
  if ((0, responsePayload_1.isSuccessResponse)(response) && response.data != null) {
18
32
  return (0, rxjs_1.of)((0, tenantReducer_1.sendEmailMagicLinkToUserSuccess)(response.data.code_verifier));
@@ -0,0 +1,28 @@
1
+ import { ActionsObservable, StateObservable } from 'redux-observable';
2
+ import { RootState } from '../../../reducer';
3
+ import { ZeniAPI } from '../../../zeniAPI';
4
+ import { updateLoggedInUser, verifyDeviceWithTwoFA, verifyDeviceWithTwoFAFailure, verifyDeviceWithTwoFASuccess } from '../tenantReducer';
5
+ export type ActionType = ReturnType<typeof verifyDeviceWithTwoFA> | ReturnType<typeof updateLoggedInUser> | ReturnType<typeof verifyDeviceWithTwoFASuccess> | ReturnType<typeof verifyDeviceWithTwoFAFailure>;
6
+ export declare const verifyDeviceWithTwoFAEpic: (actions$: ActionsObservable<ActionType>, _: StateObservable<RootState>, zeniAPI: ZeniAPI) => import("rxjs").Observable<{
7
+ payload: {
8
+ userPayload: import("../tenantPayload").LoggedInUserPayload;
9
+ zeniSessionId: string;
10
+ authProvider: import("../tenantReducer").AuthProvider;
11
+ };
12
+ type: "tenant/updateLoggedInUser";
13
+ } | {
14
+ payload: {
15
+ userId: string;
16
+ zeniSessionId: string | undefined;
17
+ };
18
+ type: "tenant/fetchAllTenants";
19
+ } | {
20
+ payload: {
21
+ userId: string;
22
+ sessionId: string;
23
+ };
24
+ type: "tenant/verifyDeviceWithTwoFASuccess";
25
+ } | {
26
+ payload: import("../../../responsePayload").ZeniAPIStatus<Record<string, unknown>>;
27
+ type: "tenant/verifyDeviceWithTwoFAFailure";
28
+ }>;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.verifyDeviceWithTwoFAEpic = void 0;
4
+ const rxjs_1 = require("rxjs");
5
+ const operators_1 = require("rxjs/operators");
6
+ const systemInfo_1 = require("../../../commonStateTypes/systemInfo");
7
+ const responsePayload_1 = require("../../../responsePayload");
8
+ const tenantReducer_1 = require("../tenantReducer");
9
+ const toRequestPayload = (otp, deviceId, userEmail, otpChallenge) => {
10
+ const systemInfo = (0, systemInfo_1.collectSystemInfo)();
11
+ return {
12
+ device_id: deviceId,
13
+ auth_type: 'magic_links',
14
+ otp_code: otp,
15
+ device_info: systemInfo,
16
+ otp_challenge: otpChallenge,
17
+ user_email: userEmail,
18
+ };
19
+ };
20
+ const verifyDeviceWithTwoFAEpic = (actions$, _, zeniAPI) => actions$.pipe((0, operators_1.filter)(tenantReducer_1.verifyDeviceWithTwoFA.match), (0, operators_1.switchMap)((action) => {
21
+ const { otp, deviceId, otpChallenge, userEmail } = action.payload;
22
+ return zeniAPI
23
+ .postJSON(`${zeniAPI.apiEndPoints.authMicroServiceBaseUrl}/1.0/signin`, toRequestPayload(otp, deviceId, userEmail, otpChallenge))
24
+ .pipe((0, operators_1.concatMap)((response) => {
25
+ return (0, rxjs_1.from)(response.json()).pipe((0, operators_1.mergeMap)((responseJson) => {
26
+ const signInResponse = responseJson;
27
+ const sessionId = response.headers.get('zeni-session-id');
28
+ if (response.ok &&
29
+ (0, responsePayload_1.isSuccessResponse)(responseJson) &&
30
+ signInResponse.data != null &&
31
+ signInResponse.data.user != null &&
32
+ sessionId != null) {
33
+ return (0, rxjs_1.of)((0, tenantReducer_1.updateLoggedInUser)(signInResponse.data.user, sessionId, 'email'), (0, tenantReducer_1.verifyDeviceWithTwoFASuccess)(signInResponse.data.user.user_id, sessionId), (0, tenantReducer_1.fetchAllTenants)(signInResponse.data.user.user_id, sessionId));
34
+ }
35
+ else {
36
+ return (0, rxjs_1.of)((0, tenantReducer_1.verifyDeviceWithTwoFAFailure)(responseJson.status));
37
+ }
38
+ }));
39
+ }), (0, operators_1.catchError)((error) => (0, rxjs_1.of)((0, tenantReducer_1.verifyDeviceWithTwoFAFailure)((0, responsePayload_1.createZeniAPIStatus)('Unexpected error', 'Verify device with two FA API call errored out: ' +
40
+ JSON.stringify(error))))));
41
+ }));
42
+ exports.verifyDeviceWithTwoFAEpic = verifyDeviceWithTwoFAEpic;
@@ -1,5 +1,6 @@
1
1
  import { URLPayload } from '../../commonPayloadTypes/urlPayload';
2
2
  import { ID } from '../../commonStateTypes/common';
3
+ import { SystemInfo } from '../../commonStateTypes/systemInfo';
3
4
  import { ZeniAPIResponse } from '../../responsePayload';
4
5
  import { CompanyPayload, UserReimbursementInfoDataPayload } from '../company/companyPayload';
5
6
  import { SubscriptionSummaryPayload } from '../subscription/subscriptionSummary/subscriptionSummaryPayload';
@@ -90,6 +91,7 @@ interface TenantPayload {
90
91
  interface LoggedInUserPayload {
91
92
  first_name: string | null;
92
93
  last_name: string | null;
94
+ phone_number: string | null;
93
95
  photo: URLPayload;
94
96
  user_id: ID;
95
97
  }
@@ -97,7 +99,10 @@ interface UserData {
97
99
  user: LoggedInUserPayload;
98
100
  }
99
101
  interface MagicLinkSignInData {
100
- user: LoggedInUserPayload;
102
+ otp_challenge?: string;
103
+ phone_number?: string;
104
+ user?: LoggedInUserPayload;
105
+ user_email?: string;
101
106
  }
102
107
  interface Session {
103
108
  session_id: ID;
@@ -105,9 +110,14 @@ interface Session {
105
110
  interface sendEmailMagicLinkToUserData {
106
111
  code_verifier: string;
107
112
  email: string;
113
+ system_info?: SystemInfo;
114
+ }
115
+ interface VerifyDeviceWithTwoFAData {
116
+ user: LoggedInUserPayload;
108
117
  }
109
118
  type SignInResponse = ZeniAPIResponse<UserData>;
110
119
  type MagicLinkSignInResponse = ZeniAPIResponse<MagicLinkSignInData>;
120
+ type VerifyDeviceWithTwoFAResponse = ZeniAPIResponse<VerifyDeviceWithTwoFAData>;
111
121
  type sendEmailMagicLinkToUserResponse = ZeniAPIResponse<sendEmailMagicLinkToUserData>;
112
122
  type SignOutResponse = ZeniAPIResponse<Session>;
113
123
  interface RoleResourcePayload {
@@ -154,4 +164,4 @@ type SaveConnectionResponse = ZeniAPIResponse<ConnectionDataPayload>;
154
164
  type SubscriptionSummaryForTenantResponse = ZeniAPIResponse<SubscriptionSummaryPayload>;
155
165
  type OnboardingTenantResponse = ZeniAPIResponse<TenantPayload>;
156
166
  /** Lets export interfaces and types */
157
- export { TenantsResponse, TenantPayload, LoggedInUserPayload, UserData, SignInResponse, SignOutResponse, RoleResourcePayload, RoleResourcesResponse, ConnectionsPayload, ConnectionWithMetaPayload, ConnectionsResponse, SaveConnectionResponse, SubscriptionSummaryForTenantResponse, OnboardingTenantResponse, MagicLinkSignInResponse, sendEmailMagicLinkToUserResponse, };
167
+ export { TenantsResponse, TenantPayload, LoggedInUserPayload, UserData, SignInResponse, SignOutResponse, RoleResourcePayload, RoleResourcesResponse, ConnectionsPayload, ConnectionWithMetaPayload, ConnectionsResponse, SaveConnectionResponse, SubscriptionSummaryForTenantResponse, OnboardingTenantResponse, MagicLinkSignInResponse, sendEmailMagicLinkToUserResponse, VerifyDeviceWithTwoFAResponse, };
@@ -34,14 +34,18 @@ export declare const updateTenants: import("@reduxjs/toolkit").ActionCreatorWith
34
34
  }, "tenant/updateExcludedResourcesSuccess", never, never>, updateExcludedResourcesFailure: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[tenantId: string, status: ZeniAPIStatus<Record<string, unknown>>], {
35
35
  tenantId: string;
36
36
  status: ZeniAPIStatus<Record<string, unknown>>;
37
- }, "tenant/updateExcludedResourcesFailure", never, never>, doSignIn: import("@reduxjs/toolkit").ActionCreatorWithPayload<DoSignInPayload, "tenant/doSignIn">, doMagicLinkSignIn: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[token: string, magicLinkCodeVerifier: string], {
37
+ }, "tenant/updateExcludedResourcesFailure", never, never>, doSignIn: import("@reduxjs/toolkit").ActionCreatorWithPayload<DoSignInPayload, "tenant/doSignIn">, doMagicLinkSignIn: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[token: string, deviceId: string, magicLinkCodeVerifier?: string | undefined, isOtpResend?: boolean | undefined, email?: string | undefined], {
38
38
  token: string;
39
- magicLinkCodeVerifier: string;
39
+ deviceId: string;
40
+ isOtpResend: boolean | undefined;
41
+ email: string | undefined;
42
+ magicLinkCodeVerifier: string | undefined;
40
43
  }, "tenant/doMagicLinkSignIn", never, never>, magicLinkSignInSuccess: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[userId: string, sessionId: string], {
41
44
  userId: string;
42
45
  sessionId: string;
43
- }, "tenant/magicLinkSignInSuccess", never, never>, magicLinkSignInFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "tenant/magicLinkSignInFailure">, sendEmailMagicLinkToUser: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[email: string], {
46
+ }, "tenant/magicLinkSignInSuccess", never, never>, magicLinkSignInFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "tenant/magicLinkSignInFailure">, sendEmailMagicLinkToUser: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[email: string, deviceId: string], {
44
47
  email: string;
48
+ deviceId: string;
45
49
  }, "tenant/sendEmailMagicLinkToUser", never, never>, sendEmailMagicLinkToUserSuccess: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[codeVerifier: string], {
46
50
  codeVerifier: string;
47
51
  }, "tenant/sendEmailMagicLinkToUserSuccess", never, never>, sendEmailMagicLinkToUserFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "tenant/sendEmailMagicLinkToUserFailure">, updateSignInState: import("@reduxjs/toolkit").ActionCreatorWithPayload<FetchState, "tenant/updateSignInState">, doSignOut: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"tenant/doSignOut">, signOutSuccess: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"tenant/signOutSuccess">, updateLoggedInUser: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[userPayload: LoggedInUserPayload, zeniSessionId: string, authProvider: AuthProvider], {
@@ -82,7 +86,19 @@ export declare const updateTenants: import("@reduxjs/toolkit").ActionCreatorWith
82
86
  }, "tenant/updateSubscriptionSummaryForTenantFailure", never, never>, updateOnboardingTenants: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[tenants: TenantPayload[], tenantUpdated?: any], {
83
87
  tenants: TenantPayload[];
84
88
  tenantUpdated: any;
85
- }, "tenant/updateOnboardingTenants", never, never>, removeOnboardingTenant: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "tenant/removeOnboardingTenant">, updateTenantReimbursementInfo: import("@reduxjs/toolkit").ActionCreatorWithPayload<UserRolePayload, "tenant/updateTenantReimbursementInfo">, updateReferViewedForLoggedInUser: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"tenant/updateReferViewedForLoggedInUser">, resetSignInState: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"tenant/resetSignInState">, updateTenantMasterTOSInfo: import("@reduxjs/toolkit").ActionCreatorWithPayload<UserRolePayload, "tenant/updateTenantMasterTOSInfo">;
89
+ }, "tenant/updateOnboardingTenants", never, never>, removeOnboardingTenant: import("@reduxjs/toolkit").ActionCreatorWithPayload<string, "tenant/removeOnboardingTenant">, updateTenantReimbursementInfo: import("@reduxjs/toolkit").ActionCreatorWithPayload<UserRolePayload, "tenant/updateTenantReimbursementInfo">, updateReferViewedForLoggedInUser: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"tenant/updateReferViewedForLoggedInUser">, resetSignInState: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"tenant/resetSignInState">, trigger2FA: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[otpChallenge: string, userEmail: string, twoFAPhoneNumber: string], {
90
+ otpChallenge: string;
91
+ userEmail: string;
92
+ twoFAPhoneNumber: string;
93
+ }, "tenant/trigger2FA", never, never>, updateTenantMasterTOSInfo: import("@reduxjs/toolkit").ActionCreatorWithPayload<UserRolePayload, "tenant/updateTenantMasterTOSInfo">, verifyDeviceWithTwoFA: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[otp: any, deviceId: any, userEmail: any, otpChallenge: any], {
94
+ otp: any;
95
+ deviceId: any;
96
+ userEmail: any;
97
+ otpChallenge: any;
98
+ }, "tenant/verifyDeviceWithTwoFA", never, never>, verifyDeviceWithTwoFASuccess: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[userId: string, sessionId: string], {
99
+ userId: string;
100
+ sessionId: string;
101
+ }, "tenant/verifyDeviceWithTwoFASuccess", never, never>, verifyDeviceWithTwoFAFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<ZeniAPIStatus<Record<string, unknown>>, "tenant/verifyDeviceWithTwoFAFailure">;
86
102
  declare const _default: import("redux").Reducer<TenantState>;
87
103
  export default _default;
88
104
  export declare const toRoleResource: (payload: RoleResourcePayload) => RoleResource;