@fat-zebra/sdk 1.0.2 → 1.0.4
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/fat-zebra-sdk-1.0.2.tgz +0 -0
- package/package.json +1 -1
- package/src/index.ts +0 -9
- package/src/react/VerifyCard.tsx +0 -36
- package/src/react/index.ts +0 -3
- package/src/react/url.ts +0 -97
- package/src/react/useFatZebra.ts +0 -154
- package/src/sca/__tests__/eci-mappings.test.ts +0 -35
- package/src/sca/__tests__/index.test.ts +0 -514
- package/src/sca/cardinal.ts +0 -136
- package/src/sca/eci-mappings.ts +0 -63
- package/src/sca/index.ts +0 -329
- package/src/sca/scenarios/enrollment.ts +0 -164
- package/src/sca/scenarios/index.ts +0 -4
- package/src/sca/scenarios/validation.ts +0 -142
- package/src/sca/types.ts +0 -209
- package/src/shared/api-gateway-client.ts +0 -71
- package/src/shared/bridge-client.ts +0 -26
- package/src/shared/constants.ts +0 -19
- package/src/shared/event-manager.ts +0 -45
- package/src/shared/post-message-client.test.ts +0 -73
- package/src/shared/post-message-client.ts +0 -127
- package/src/shared/types.test.ts +0 -65
- package/src/shared/types.ts +0 -182
- package/src/shared/util.test.ts +0 -164
- package/src/shared/util.ts +0 -98
- package/tests/helpers/api-gateway-mock.ts +0 -46
package/src/sca/index.ts
DELETED
|
@@ -1,329 +0,0 @@
|
|
|
1
|
-
import * as t from './types'
|
|
2
|
-
import {
|
|
3
|
-
EnrollmentScenario,
|
|
4
|
-
enrollmentScenarios,
|
|
5
|
-
ValidationScenario,
|
|
6
|
-
validationScenarios,
|
|
7
|
-
} from './scenarios'
|
|
8
|
-
import {
|
|
9
|
-
Customer,
|
|
10
|
-
CustomerSnakeCase,
|
|
11
|
-
PaymentIntent,
|
|
12
|
-
PublicEvent,
|
|
13
|
-
} from '../shared/types'
|
|
14
|
-
import {
|
|
15
|
-
CardinalManager,
|
|
16
|
-
PaymentValidatedDTO,
|
|
17
|
-
} from './cardinal'
|
|
18
|
-
import {
|
|
19
|
-
emit,
|
|
20
|
-
} from '../shared/event-manager'
|
|
21
|
-
import { toFzSli } from './eci-mappings'
|
|
22
|
-
import { ThreedsData } from './types'
|
|
23
|
-
import GatewayClient from '../shared/api-gateway-client'
|
|
24
|
-
|
|
25
|
-
export interface ScaRunProps {
|
|
26
|
-
cardToken: string
|
|
27
|
-
customer?: Customer
|
|
28
|
-
paymentIntent: PaymentIntent
|
|
29
|
-
bin: string
|
|
30
|
-
challengeWindowSize?: t.ChallengeWindowSize
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export interface ScaConfig {
|
|
34
|
-
gatewayClient: GatewayClient,
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
class Sca {
|
|
38
|
-
private _cardinal: CardinalManager
|
|
39
|
-
private _eventEmitTarget: HTMLDivElement | Window
|
|
40
|
-
private enrollmentResult: t.EnrollSCAResponse
|
|
41
|
-
private paymentIntent: PaymentIntent
|
|
42
|
-
private bin: string
|
|
43
|
-
private cardToken: string
|
|
44
|
-
private customer: Customer
|
|
45
|
-
private challengeWindowSize: t.ChallengeWindowSize
|
|
46
|
-
private sessionId: string
|
|
47
|
-
private gatewayClient: GatewayClient
|
|
48
|
-
|
|
49
|
-
constructor({ gatewayClient }: ScaConfig) {
|
|
50
|
-
this._eventEmitTarget = window;
|
|
51
|
-
this.sessionId = null;
|
|
52
|
-
this.gatewayClient = gatewayClient;
|
|
53
|
-
|
|
54
|
-
this.loadScript()
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
loadScript(): void {
|
|
58
|
-
if (!document.getElementById("songbird-script")) {
|
|
59
|
-
const script: HTMLScriptElement = document.createElement('script')
|
|
60
|
-
script.type = 'text/javascript';
|
|
61
|
-
script.id = "songbird-script"
|
|
62
|
-
script.src = process.env.SONGBIRD_URL
|
|
63
|
-
script.async = true;
|
|
64
|
-
script.onload = () => {
|
|
65
|
-
this._cardinal = new CardinalManager()
|
|
66
|
-
};
|
|
67
|
-
document.body.appendChild(script);
|
|
68
|
-
} else {
|
|
69
|
-
this._cardinal = new CardinalManager()
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
get cardinal(): CardinalManager {
|
|
74
|
-
return this._cardinal
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
set cardinal(cardinal: CardinalManager) {
|
|
78
|
-
this._cardinal = cardinal
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
get eventEmitTarget(): HTMLDivElement | Window {
|
|
82
|
-
return this._eventEmitTarget
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Specify the DOM element to which the SCA results are outputted.
|
|
86
|
-
set eventEmitTarget(target: HTMLDivElement | Window) {
|
|
87
|
-
this._eventEmitTarget = target
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
async run(config: ScaRunProps): Promise<void> {
|
|
91
|
-
// Persist states until next 3DS run.
|
|
92
|
-
this.paymentIntent = config.paymentIntent
|
|
93
|
-
this.bin = config.bin
|
|
94
|
-
this.cardToken = config.cardToken
|
|
95
|
-
this.customer = config.customer
|
|
96
|
-
this.challengeWindowSize = config.challengeWindowSize || t.ChallengeWindowSize.SIZE_FULL_PAGE
|
|
97
|
-
|
|
98
|
-
let cardinalJwt: string
|
|
99
|
-
|
|
100
|
-
// Generate Cardinal JWT
|
|
101
|
-
try {
|
|
102
|
-
cardinalJwt = await this.createCardinalJWT()
|
|
103
|
-
} catch (error) {
|
|
104
|
-
const message = 'FatZebra.3DS: JWT creation failed.'
|
|
105
|
-
emit(PublicEvent.SCA_ERROR, {
|
|
106
|
-
errors: [message],
|
|
107
|
-
data: null
|
|
108
|
-
})
|
|
109
|
-
console.log(message)
|
|
110
|
-
return
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// Init cardinal
|
|
114
|
-
this._cardinal.setup(cardinalJwt)
|
|
115
|
-
|
|
116
|
-
if (!this.sessionId) {
|
|
117
|
-
const paymentsSetupCompleteResponse = await this._cardinal.onPaymentSetupComplete()
|
|
118
|
-
this.sessionId = paymentsSetupCompleteResponse.sessionId
|
|
119
|
-
|
|
120
|
-
// Register handler. Called after OTP is entered on challenge prompt.
|
|
121
|
-
this._cardinal.onPaymentValidated(async (data: PaymentValidatedDTO, error: string): Promise<void> => {
|
|
122
|
-
if (typeof error == 'string') {
|
|
123
|
-
const message = `FatZebra.3DS: Validation failed. ${error}.`
|
|
124
|
-
emit(PublicEvent.SCA_ERROR, {
|
|
125
|
-
errors: [message],
|
|
126
|
-
data: null,
|
|
127
|
-
})
|
|
128
|
-
console.log(message)
|
|
129
|
-
return
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const decodeSCASessionResponse = (await this.gatewayClient.decodeSCASession({
|
|
133
|
-
token: data.jwt
|
|
134
|
-
})).data as t.DecodeSCASessionResponse
|
|
135
|
-
|
|
136
|
-
if (data.processorTransactionId !== decodeSCASessionResponse.processor_transaction_id) {
|
|
137
|
-
const message = 'FatZebra.3DS: Validation failed. Invalid process transaction id.'
|
|
138
|
-
emit(PublicEvent.SCA_ERROR, {
|
|
139
|
-
errors: [message],
|
|
140
|
-
data: null
|
|
141
|
-
})
|
|
142
|
-
console.log(message)
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
let validateSCAResponse
|
|
146
|
-
|
|
147
|
-
try {
|
|
148
|
-
const requestParams: t.ValidateSCARequest = {
|
|
149
|
-
amount: this.paymentIntent.payment.amount,
|
|
150
|
-
authentication_transaction_id: this.enrollmentResult.authentication_transaction_id,
|
|
151
|
-
card_token: this.cardToken,
|
|
152
|
-
currency: this.paymentIntent.payment.currency,
|
|
153
|
-
pareq: this.enrollmentResult.pareq,
|
|
154
|
-
reference: this.paymentIntent.payment.reference,
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
validateSCAResponse = (await this.gatewayClient.validateSCA(requestParams)).data as t.ValidateSCAResponse
|
|
158
|
-
|
|
159
|
-
} catch (errorResponse) {
|
|
160
|
-
const message = 'FatZebra.3DS: Validation failed. Server error.'
|
|
161
|
-
emit(PublicEvent.SCA_ERROR, {
|
|
162
|
-
errors: [message],
|
|
163
|
-
data: null,
|
|
164
|
-
})
|
|
165
|
-
console.log(message)
|
|
166
|
-
return
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
const threedsData = threedsResponseData(validateSCAResponse)
|
|
170
|
-
const scenario: ValidationScenario = getValidationResult(validateSCAResponse)
|
|
171
|
-
|
|
172
|
-
if (scenario.outcome.success) {
|
|
173
|
-
const message = `FatZebra.3DS: 3DS success - ${scenario.description}.`
|
|
174
|
-
emit(PublicEvent.SCA_SUCCESS, {
|
|
175
|
-
message,
|
|
176
|
-
data: threedsData,
|
|
177
|
-
})
|
|
178
|
-
console.log(message)
|
|
179
|
-
} else {
|
|
180
|
-
const message = `FatZebra.3DS: 3DS error - ${scenario.description}`
|
|
181
|
-
emit(PublicEvent.SCA_ERROR, {
|
|
182
|
-
errors: [message],
|
|
183
|
-
data: {
|
|
184
|
-
errorCode: scenario.outcome.errorCode
|
|
185
|
-
},
|
|
186
|
-
})
|
|
187
|
-
console.log(message)
|
|
188
|
-
}
|
|
189
|
-
})
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Cardinal processs BIN using directory server. This determines the 3DS version used.
|
|
193
|
-
try {
|
|
194
|
-
await this._cardinal.processBin(this.bin)
|
|
195
|
-
} catch (err) {
|
|
196
|
-
const message = 'FatZebra.3DS: BIN verification failed.'
|
|
197
|
-
emit(PublicEvent.SCA_ERROR, {
|
|
198
|
-
errors: [message],
|
|
199
|
-
data: null
|
|
200
|
-
})
|
|
201
|
-
console.log(message)
|
|
202
|
-
return
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
try {
|
|
206
|
-
await this.check3DSEnrollment()
|
|
207
|
-
} catch (err) {
|
|
208
|
-
const message = 'FatZebra.3DS: Enrollment failed. Server error.'
|
|
209
|
-
emit(PublicEvent.SCA_ERROR, {
|
|
210
|
-
errors: [message],
|
|
211
|
-
data: null
|
|
212
|
-
})
|
|
213
|
-
console.log(message)
|
|
214
|
-
return
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
this.handleEnrollmentResult(this.enrollmentResult)
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
async createCardinalJWT(): Promise<string> {
|
|
221
|
-
const { payment } = this.paymentIntent
|
|
222
|
-
const response = (await this.gatewayClient.createSCASession({
|
|
223
|
-
amount: payment.amount,
|
|
224
|
-
currency: payment.currency,
|
|
225
|
-
hide_card_holder: payment.hide_card_holder,
|
|
226
|
-
})).data as t.CreateSCASessionResponse
|
|
227
|
-
|
|
228
|
-
return response.jwt
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
async check3DSEnrollment(): Promise<void> {
|
|
232
|
-
// Persist enrollResult state in memory for handlePaymentValidation handler
|
|
233
|
-
this.enrollmentResult = (await this.gatewayClient.enrolSCA({
|
|
234
|
-
amount: this.paymentIntent.payment.amount,
|
|
235
|
-
card_token: this.cardToken,
|
|
236
|
-
currency: this.paymentIntent.payment.currency,
|
|
237
|
-
reference: this.paymentIntent.payment.reference,
|
|
238
|
-
verification: this.paymentIntent.verification,
|
|
239
|
-
session_id: this.sessionId,
|
|
240
|
-
challenge_window_size: this.challengeWindowSize,
|
|
241
|
-
hide_card_holder: this.paymentIntent.payment.hide_card_holder,
|
|
242
|
-
customer: this.customerProperties(this.customer),
|
|
243
|
-
})).data as t.EnrollSCAResponse
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
customerProperties(customer: Customer): CustomerSnakeCase {
|
|
247
|
-
let properties: CustomerSnakeCase = {};
|
|
248
|
-
if (!customer) return properties;
|
|
249
|
-
if (customer.firstName) properties.first_name = customer.firstName
|
|
250
|
-
if (customer.lastName) properties.last_name = customer.lastName
|
|
251
|
-
if (customer.email) properties.email = customer.email
|
|
252
|
-
if (customer.address) properties.address = customer.address
|
|
253
|
-
if (customer.city) properties.city = customer.city
|
|
254
|
-
if (customer.state) properties.state = customer.state
|
|
255
|
-
if (customer.postcode) properties.postcode = customer.postcode
|
|
256
|
-
if (customer.country) properties.country = customer.country
|
|
257
|
-
return properties
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
handleEnrollmentResult(enrollSCAResponse: t.EnrollSCAResponse): void {
|
|
261
|
-
const threedsData = threedsResponseData(enrollSCAResponse)
|
|
262
|
-
const scenario: EnrollmentScenario = getEnrollmentResult(enrollSCAResponse)
|
|
263
|
-
|
|
264
|
-
if (scenario.outcome.authenticationType === 'challenge') {
|
|
265
|
-
this._cardinal.continue(
|
|
266
|
-
enrollSCAResponse.acs_url,
|
|
267
|
-
enrollSCAResponse.pareq,
|
|
268
|
-
enrollSCAResponse.authentication_transaction_id
|
|
269
|
-
)
|
|
270
|
-
return
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
if (scenario.outcome.success) {
|
|
274
|
-
const message = `FatZebra.3DS: 3DS success - ${scenario.description}.`
|
|
275
|
-
emit(PublicEvent.SCA_SUCCESS, {
|
|
276
|
-
message,
|
|
277
|
-
data: threedsData,
|
|
278
|
-
})
|
|
279
|
-
console.log(message)
|
|
280
|
-
} else {
|
|
281
|
-
const message = `FatZebra.3DS: 3DS error - ${scenario.description}`
|
|
282
|
-
emit(PublicEvent.SCA_ERROR, {
|
|
283
|
-
errors: [message],
|
|
284
|
-
data: {
|
|
285
|
-
errorCode: scenario.outcome.errorCode
|
|
286
|
-
},
|
|
287
|
-
})
|
|
288
|
-
console.log(message)
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
const threedsResponseData = (response: t.EnrollSCAResponse | t.ValidateSCAResponse): ThreedsData => {
|
|
294
|
-
return {
|
|
295
|
-
// CAVV: Visa & Amex only
|
|
296
|
-
// AAV: Mastercard only, known as UCAF
|
|
297
|
-
cavv: response.cavv || response.aav,
|
|
298
|
-
par: response.pares,
|
|
299
|
-
sli: toFzSli(response.eci),
|
|
300
|
-
xid: response.xid,
|
|
301
|
-
ver: response.enrolled,
|
|
302
|
-
directoryServerTxnId: response.directory_server_txn_id,
|
|
303
|
-
threedsVersion: response.version,
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
const getEnrollmentResult = (enrollment: t.EnrollSCAResponse): EnrollmentScenario => {
|
|
308
|
-
return enrollmentScenarios.find((item: EnrollmentScenario) => {
|
|
309
|
-
return item.reasonCode === enrollment.reason_code &&
|
|
310
|
-
item.veresEnrolled === enrollment.enrolled &&
|
|
311
|
-
item.pares === enrollment.pares &&
|
|
312
|
-
item.threedsVersion === getMajor3dsVersion(enrollment.version)
|
|
313
|
-
})
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
const getValidationResult = (validation: t.ValidateSCAResponse): ValidationScenario => {
|
|
317
|
-
return validationScenarios.find((item: ValidationScenario) => {
|
|
318
|
-
return item.reasonCode === validation.reason_code &&
|
|
319
|
-
item.pares === validation.pares &&
|
|
320
|
-
item.threedsVersion === getMajor3dsVersion(validation.version)
|
|
321
|
-
})
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
// 3DS versioning follows SEMVER format. The first charactor is the major version number.
|
|
325
|
-
const getMajor3dsVersion = (original: string): string => {
|
|
326
|
-
return original[0]
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
export default Sca;
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import { ScaErrorCode, VEResEnrolled, PARes } from '../types'
|
|
2
|
-
|
|
3
|
-
interface EnrollmentScenario {
|
|
4
|
-
description: string
|
|
5
|
-
threedsVersion: '1' | '2'
|
|
6
|
-
reasonCode: string
|
|
7
|
-
veresEnrolled: VEResEnrolled
|
|
8
|
-
pares: PARes | null // null is for challenge
|
|
9
|
-
outcome: {
|
|
10
|
-
authenticationType?: 'bypass' | 'frictionless' | 'challenge'
|
|
11
|
-
success: boolean
|
|
12
|
-
errorCode?: string
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const enrollmentScenarios: EnrollmentScenario[] = [
|
|
17
|
-
/***************************************************************/
|
|
18
|
-
/********************** 3DS2 scenarios *************************/
|
|
19
|
-
/***************************************************************/
|
|
20
|
-
{
|
|
21
|
-
// Bypassed Authentication
|
|
22
|
-
description: 'Bypassed Authentication',
|
|
23
|
-
threedsVersion: '2',
|
|
24
|
-
reasonCode: '100',
|
|
25
|
-
veresEnrolled: VEResEnrolled.BYPASSED,
|
|
26
|
-
pares: null,
|
|
27
|
-
outcome: {
|
|
28
|
-
success: false, // no liability shift
|
|
29
|
-
authenticationType: 'bypass',
|
|
30
|
-
errorCode: ScaErrorCode.BYPASSED_AUTHENTICATION
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
// Authentication not Available on Lookup
|
|
35
|
-
description: 'Authentication not Available on Lookup ',
|
|
36
|
-
threedsVersion: '2',
|
|
37
|
-
reasonCode: '100',
|
|
38
|
-
veresEnrolled: VEResEnrolled.UNABLE,
|
|
39
|
-
pares: null,
|
|
40
|
-
outcome: {
|
|
41
|
-
success: false, // no liability shift
|
|
42
|
-
errorCode: ScaErrorCode.AUTHENTICATION_NOT_AVAILABLE_ON_LOOKUP
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
// Attempts Processing Frictionless Authentication
|
|
47
|
-
description: 'Attempts Processing Frictionless Authentication',
|
|
48
|
-
threedsVersion: '2',
|
|
49
|
-
reasonCode: '100',
|
|
50
|
-
veresEnrolled: VEResEnrolled.ENROLLED,
|
|
51
|
-
pares: PARes.ATTEMPTED,
|
|
52
|
-
outcome: {
|
|
53
|
-
authenticationType: 'frictionless',
|
|
54
|
-
success: true
|
|
55
|
-
}
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
// Successful Frictionless Authentication
|
|
59
|
-
description: 'Successful Frictionless Authentication',
|
|
60
|
-
threedsVersion: '2',
|
|
61
|
-
reasonCode: '100',
|
|
62
|
-
veresEnrolled: VEResEnrolled.ENROLLED,
|
|
63
|
-
pares: PARes.SUCCESS,
|
|
64
|
-
outcome: {
|
|
65
|
-
authenticationType: 'frictionless',
|
|
66
|
-
success: true
|
|
67
|
-
}
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
// Unavailable Frictionless Authentication
|
|
71
|
-
description: 'Unavailable Frictionless Authentication',
|
|
72
|
-
threedsVersion: '2',
|
|
73
|
-
reasonCode: '100',
|
|
74
|
-
veresEnrolled: VEResEnrolled.ENROLLED,
|
|
75
|
-
pares: PARes.NOT_COMPLETED,
|
|
76
|
-
outcome: {
|
|
77
|
-
authenticationType: 'frictionless',
|
|
78
|
-
success: false,
|
|
79
|
-
errorCode: ScaErrorCode.UNAVAILABLE_FRICTIONLESS_AUTHENTICATION
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
{
|
|
83
|
-
// Challenge. Continue with OTP prompt
|
|
84
|
-
description: 'Challenge. Continue with OTP prompt',
|
|
85
|
-
threedsVersion: '2',
|
|
86
|
-
reasonCode: '475',
|
|
87
|
-
veresEnrolled: VEResEnrolled.ENROLLED,
|
|
88
|
-
pares: null,
|
|
89
|
-
outcome: {
|
|
90
|
-
authenticationType: 'challenge',
|
|
91
|
-
success: true
|
|
92
|
-
}
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
// Unsuccessful Frictionless Authentication
|
|
96
|
-
description: 'Unsuccessful Frictionless Authentication',
|
|
97
|
-
threedsVersion: '2',
|
|
98
|
-
reasonCode: '476',
|
|
99
|
-
veresEnrolled: VEResEnrolled.ENROLLED,
|
|
100
|
-
pares: PARes.CANCELED,
|
|
101
|
-
outcome: {
|
|
102
|
-
authenticationType: 'frictionless',
|
|
103
|
-
success: false,
|
|
104
|
-
errorCode: ScaErrorCode.UNSUCCESSFUL_FRICTIONLESS_AUTHENTICATION
|
|
105
|
-
}
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
// Rejected Frictionless Authentication
|
|
109
|
-
description: 'Rejected Frictionless Authentication',
|
|
110
|
-
threedsVersion: '2',
|
|
111
|
-
reasonCode: '476',
|
|
112
|
-
veresEnrolled: VEResEnrolled.ENROLLED,
|
|
113
|
-
pares: PARes.REJECTED,
|
|
114
|
-
outcome: {
|
|
115
|
-
authenticationType: 'frictionless',
|
|
116
|
-
success: false,
|
|
117
|
-
errorCode: ScaErrorCode.REJECTED_FRICTIONLESS_AUTHENTICATION
|
|
118
|
-
}
|
|
119
|
-
},
|
|
120
|
-
/***************************************************************/
|
|
121
|
-
/********************** 3DS1 scenarios *************************/
|
|
122
|
-
/***************************************************************/
|
|
123
|
-
{
|
|
124
|
-
// Proceed to challenge step
|
|
125
|
-
description: '*****',
|
|
126
|
-
threedsVersion: '1',
|
|
127
|
-
reasonCode: '475',
|
|
128
|
-
veresEnrolled: VEResEnrolled.ENROLLED,
|
|
129
|
-
pares: null,
|
|
130
|
-
outcome: {
|
|
131
|
-
authenticationType: 'challenge',
|
|
132
|
-
success: true
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
// Error, Unavailable Authentication
|
|
137
|
-
description: 'Error; Unavailable Authentication',
|
|
138
|
-
threedsVersion: '1',
|
|
139
|
-
reasonCode: '100',
|
|
140
|
-
veresEnrolled: VEResEnrolled.UNABLE,
|
|
141
|
-
pares: null,
|
|
142
|
-
outcome: {
|
|
143
|
-
authenticationType: 'frictionless',
|
|
144
|
-
success: false
|
|
145
|
-
}
|
|
146
|
-
},
|
|
147
|
-
{
|
|
148
|
-
// Not Enrolled
|
|
149
|
-
description: 'Not Enrolled',
|
|
150
|
-
threedsVersion: '1',
|
|
151
|
-
reasonCode: '100',
|
|
152
|
-
veresEnrolled: VEResEnrolled.NOT_ENROLLED,
|
|
153
|
-
pares: null,
|
|
154
|
-
outcome: {
|
|
155
|
-
authenticationType: 'frictionless',
|
|
156
|
-
success: true
|
|
157
|
-
}
|
|
158
|
-
},
|
|
159
|
-
]
|
|
160
|
-
|
|
161
|
-
export {
|
|
162
|
-
enrollmentScenarios
|
|
163
|
-
}
|
|
164
|
-
export type { EnrollmentScenario }
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import { ScaErrorCode, VEResEnrolled, PARes } from '../types'
|
|
2
|
-
|
|
3
|
-
interface ValidationScenario {
|
|
4
|
-
description: string
|
|
5
|
-
threedsVersion: '1' | '2',
|
|
6
|
-
reasonCode: string
|
|
7
|
-
veresEnrolled: VEResEnrolled
|
|
8
|
-
pares: PARes | null // null is for challenge
|
|
9
|
-
outcome: {
|
|
10
|
-
authenticationType?: 'bypass' | 'frictionless' | 'challenge',
|
|
11
|
-
success: boolean,
|
|
12
|
-
errorCode?: string
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const validationScenarios: ValidationScenario[] = [
|
|
17
|
-
/***************************************************************/
|
|
18
|
-
/********************** 3DS2 scenarios *************************/
|
|
19
|
-
/***************************************************************/
|
|
20
|
-
{
|
|
21
|
-
// Successful Step-Up Authentication
|
|
22
|
-
description: 'Successful Step-Up Authentication',
|
|
23
|
-
threedsVersion: '2',
|
|
24
|
-
reasonCode: '100',
|
|
25
|
-
veresEnrolled: null,
|
|
26
|
-
pares: PARes.SUCCESS,
|
|
27
|
-
outcome: {
|
|
28
|
-
authenticationType: 'challenge',
|
|
29
|
-
success: true // liability shift
|
|
30
|
-
},
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
// Unsuccessful Step-Up Authentication
|
|
34
|
-
description: 'Unsuccessful Step-Up Authentication',
|
|
35
|
-
threedsVersion: '2',
|
|
36
|
-
reasonCode: '476',
|
|
37
|
-
veresEnrolled: null,
|
|
38
|
-
pares: PARes.CANCELED,
|
|
39
|
-
outcome: {
|
|
40
|
-
authenticationType: 'challenge',
|
|
41
|
-
success: false, // no liability shift
|
|
42
|
-
errorCode: ScaErrorCode.UNSUCCESSFUL_STEPUP_AUTHENTICATION
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
{
|
|
46
|
-
// Unavailable Step-Up Authentication
|
|
47
|
-
description: 'Unavailable Step-Up Authentication',
|
|
48
|
-
threedsVersion: '2',
|
|
49
|
-
reasonCode: '100',
|
|
50
|
-
veresEnrolled: null,
|
|
51
|
-
pares: PARes.NOT_COMPLETED,
|
|
52
|
-
outcome: {
|
|
53
|
-
authenticationType: 'challenge',
|
|
54
|
-
success: false, // no liability shift
|
|
55
|
-
errorCode: ScaErrorCode.UNAVAILABLE_STEPUP_AUTHENTICATION
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
/***************************************************************/
|
|
59
|
-
/********************** 3DS1 scenarios *************************/
|
|
60
|
-
/***************************************************************/
|
|
61
|
-
{
|
|
62
|
-
// Successful Step-Up Authentication
|
|
63
|
-
description: 'Successful Authentication',
|
|
64
|
-
threedsVersion: '1',
|
|
65
|
-
reasonCode: '100',
|
|
66
|
-
veresEnrolled: null,
|
|
67
|
-
pares: PARes.SUCCESS,
|
|
68
|
-
outcome: {
|
|
69
|
-
authenticationType: 'challenge',
|
|
70
|
-
success: true // liability shift
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
// Incomplete Authentication
|
|
75
|
-
description: 'Incomplete Authentication',
|
|
76
|
-
threedsVersion: '1',
|
|
77
|
-
reasonCode: '100',
|
|
78
|
-
veresEnrolled: null,
|
|
79
|
-
pares: PARes.NOT_COMPLETED,
|
|
80
|
-
outcome: {
|
|
81
|
-
authenticationType: 'challenge',
|
|
82
|
-
success: false,
|
|
83
|
-
errorCode: ScaErrorCode.UNAVAILABLE_STEPUP_AUTHENTICATION
|
|
84
|
-
}
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
// Attempts Processing
|
|
88
|
-
description: 'Attempts Processing',
|
|
89
|
-
threedsVersion: '1',
|
|
90
|
-
reasonCode: '100',
|
|
91
|
-
veresEnrolled: null,
|
|
92
|
-
pares: PARes.ATTEMPTED,
|
|
93
|
-
outcome: {
|
|
94
|
-
authenticationType: 'challenge',
|
|
95
|
-
success: true
|
|
96
|
-
}
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
// Unsuccessful Authentication
|
|
100
|
-
description: 'Unsuccessful Authentication',
|
|
101
|
-
threedsVersion: '1',
|
|
102
|
-
reasonCode: '476',
|
|
103
|
-
veresEnrolled: null,
|
|
104
|
-
pares: PARes.CANCELED,
|
|
105
|
-
outcome: {
|
|
106
|
-
authenticationType: 'challenge',
|
|
107
|
-
success: false,
|
|
108
|
-
errorCode: ScaErrorCode.UNSUCCESSFUL_STEPUP_AUTHENTICATION
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
// Successful Authentication But Invalid PARes
|
|
113
|
-
description: 'Successful Authentication But Invalid PARes',
|
|
114
|
-
threedsVersion: '1',
|
|
115
|
-
reasonCode: '476',
|
|
116
|
-
veresEnrolled: null,
|
|
117
|
-
pares: null,
|
|
118
|
-
outcome: {
|
|
119
|
-
authenticationType: 'challenge',
|
|
120
|
-
success: false,
|
|
121
|
-
errorCode: ScaErrorCode.UNSUCCESSFUL_STEPUP_AUTHENTICATION
|
|
122
|
-
}
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
// Authentication Error
|
|
126
|
-
description: 'Authentication Error',
|
|
127
|
-
threedsVersion: '1',
|
|
128
|
-
reasonCode: '476',
|
|
129
|
-
veresEnrolled: null,
|
|
130
|
-
pares: null,
|
|
131
|
-
outcome: {
|
|
132
|
-
authenticationType: 'challenge',
|
|
133
|
-
success: false, // no liability shift
|
|
134
|
-
errorCode: ScaErrorCode.UNSUCCESSFUL_STEPUP_AUTHENTICATION
|
|
135
|
-
}
|
|
136
|
-
},
|
|
137
|
-
]
|
|
138
|
-
|
|
139
|
-
export {
|
|
140
|
-
validationScenarios
|
|
141
|
-
}
|
|
142
|
-
export type { ValidationScenario }
|