@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.
- package/lib/commonStateTypes/animations.d.ts +1 -1
- package/lib/commonStateTypes/animations.js +4 -0
- package/lib/commonStateTypes/systemInfo.d.ts +52 -0
- package/lib/commonStateTypes/systemInfo.js +242 -0
- package/lib/entity/company/companyPayload.d.ts +1 -0
- package/lib/entity/company/companyPayload.js +1 -0
- package/lib/entity/company/companyStateTypes.d.ts +1 -0
- package/lib/entity/tenant/epic/doMagicLinkSignInEpic.d.ts +7 -0
- package/lib/entity/tenant/epic/doMagicLinkSignInEpic.js +28 -7
- package/lib/entity/tenant/epic/sendEmailMagicLinkToUserEpic.js +19 -5
- package/lib/entity/tenant/epic/verifyDeviceWithTwoFAEpic.d.ts +28 -0
- package/lib/entity/tenant/epic/verifyDeviceWithTwoFAEpic.js +42 -0
- package/lib/entity/tenant/tenantPayload.d.ts +12 -2
- package/lib/entity/tenant/tenantReducer.d.ts +20 -4
- package/lib/entity/tenant/tenantReducer.js +64 -7
- package/lib/entity/tenant/tenantState.d.ts +4 -0
- package/lib/epic.d.ts +2 -1
- package/lib/epic.js +2 -1
- package/lib/index.d.ts +4 -4
- package/lib/index.js +30 -28
- package/lib/view/addressView/__mocks__/json/createCompanyAddressSuccess.json +1 -0
- package/lib/view/addressView/__mocks__/json/createCompanyUserAddressSuccess.json +1 -0
- package/lib/view/spendManagement/helpers.d.ts +11 -0
- package/lib/view/spendManagement/helpers.js +29 -1
- package/package.json +1 -1
|
@@ -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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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">,
|
|
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;
|