UNPKG

22.1 kBJavaScriptView Raw
1import React, { Component } from 'react';
2import { connect } from 'react-redux';
3require('./array');
4import {
5 Container,
6 Header,
7 List,
8 ListItem,
9 InputGroup,
10 Input,
11 Title,
12 Content,
13 Footer,
14 FooterTab,
15 Button,
16 Picker,
17 Icon,
18 Text
19} from 'native-base';
20import * as Titles from './titles';
21import * as Common from './common';
22import * as UIA from './actions/uiActions';
23import { Colors } from './colors';
24
25export const FirstName = 'firstName';
26export const LastName = 'lastName';
27export const BusinessName = 'businessName';
28export const SupportEmail = 'supportEmail';
29export const StripeAccountLegalEntityOptions = () => {
30 return {
31 //'email': validation(['email_empty']),
32 [FirstName]: validation(['notempty', 'alphanumericlike', 'maxlength22']),
33 [LastName]: validation(['notempty', 'alphanumericlike', 'maxlength22']),
34 'maidenName': validation(['notempty', 'alphanumericlike', 'maxlength22']),
35 'personalIdNumber': validation(['notempty', 'length9']),
36 'accountNumber': validation(['notempty', 'maxlength22']),
37 'url': validation(['url_empty']),
38 [BusinessName]: validation(['notempty', 'maxlength50']),
39 'businessUrl': validation(['url_empty']),
40 [AddressCity]: validation(['notempty', 'maxlength50', 'alphanumericlike']),
41 [AddressLine1]: validation(['notempty', 'maxlength50', 'alphanumericlike']),
42 'productDescription': validation(['maxlength50', 'alphanumericlike']),
43 'statementDescriptor': validation(['maxlength22', 'alphanumericlike']),
44 [SupportEmail]: validation(['email_empty']),
45 'supportUrl': validation(['url_empty']),
46 [AddressPostalCode]: validation(['numbers', 'length5']),
47 'endDate': validation(['pastdate']),
48 };
49}
50export const AddressPostalCode = 'addressPostalCode';
51export const AddressCity = 'addressCity';
52export const AddressZip = 'addressZip';
53export const AddressLine1 = 'addressLine1';
54export function ValidatedCreditCard() {
55 return {
56 'name': validation(['notempty', 'alphanumericlike', 'maxlength50']),
57 'email': validation(['email_empty']),
58 'number': validation(['notempty', 'length14t19', 'credit']),
59 'cvc': validation(['notempty', 'length3t4']),
60 [AddressLine1]: validation(['maxlength50']),
61 'addressLine2': validation(['maxlength50']),
62 [AddressCity]: validation(['alphanumericlike']),
63 [AddressZip]: validation(['zipempty']),
64 'expirationYear': validation(['expirationYear'], {
65 year: 'expirationYear',
66 month: 'expirationMonth'
67 }),
68 'expirationMonth': validation(['expirationMonth'], {
69 year: 'expirationYear',
70 month: 'expirationMonth'
71 })
72 }
73}
74export function ValidateCreditCard(me, state) {
75 var _validation = ValidatedCreditCard();
76 var valid = validate(me, _validation, state);
77
78 me.props.UI(UIA.CREDIT_CARD_VALID, valid);
79
80 return valid;
81}
82
83export const Email = 'email';
84export function ValidateStripeManagedAccount(me, stripeState) {
85 var _validation = {
86 [Email]: validation(['email_empty']),
87 [BusinessName]: validation(['notempty', 'maxlength50', 'alphanumericlike']),
88 'businessUrl': validation(['url_empty']),
89 'productDescription': validation(['notempty', 'maxlength50']),
90 'statementDescriptor': validation(['notempty', 'maxlength22']),
91 'supportEmail': validation(['email_empty']),
92 'supportUrl': validation(['url_empty']),
93 }
94
95 var valid = validate(me, _validation, stripeState);
96 me.props.UI(LA.ADD_BANK_ACCOUNT_STATE_VALID, valid, true);
97 return valid;
98}
99
100export const PersonalAddressCity = 'personalAddressCity';
101export const PersonalAddressPostalCode = 'personalAddressPostalCode';
102export const PersonalAddressLine1 = 'personalAddressLine1';
103export function ValidateStripeAccountPersonalAddress(me, stripeState) {
104
105 var _validation = {
106 [PersonalAddressLine1]: validation(['notempty', 'maxlength50', 'alphanumericlike']),
107 [PersonalAddressCity]: validation(['notempty', 'maxlength50', 'alphanumericlike']),
108 [PersonalAddressPostalCode]: validation(['zip', 'notempty', 'numbers']),
109 }
110
111 var valid = validate(me, _validation, stripeState);
112 me.props.UI(LA.ADD_STRIPE_ACCOUNT_LEGAL_ENTITY_OPTIONS_STATE_VALID, valid);
113
114 me.props.UI(LA.ADD_STRIPE_ACCOUNT_LEGAL_ENTITY_OPTIONS_STATE, Object.assign({}, stripeState), true);
115
116}
117export function ValidateStripeAccountLegalEntityOptions(me, stripeState) {
118 var _validation = StripeAccountLegalEntityOptions();
119 var valid = validate(me, _validation, stripeState);
120
121 me.props.UI(LA.ADD_STRIPE_ACCOUNT_LEGAL_ENTITY_OPTIONS_STATE_VALID, valid);
122 me.props.UI(LA.ADD_STRIPE_ACCOUNT_LEGAL_ENTITY_OPTIONS_STATE, Object.assign({}, stripeState), true);
123
124 return valid;
125}
126
127export function validateBank(me) {
128
129 var { state } = me.props;
130
131 var ADD_STRIPE_ACCOUNT_BANK_ACCOUNT_OPTIONS = UIA.Get(state, LA.ADD_STRIPE_ACCOUNT_BANK_ACCOUNT_OPTIONS) || {};
132 var ADD_BANK_ACCOUNT_STATE = UIA.Get(state, LA.ADD_BANK_ACCOUNT_STATE);
133 var ADD_STRIPE_ACCOUNT_LEGAL_ENTITY_OPTIONS_STATE = UIA.Get(state, LA.ADD_STRIPE_ACCOUNT_LEGAL_ENTITY_OPTIONS_STATE) || {};
134
135 return ValidateStripeAccountBankAccountOptions(me, ADD_STRIPE_ACCOUNT_BANK_ACCOUNT_OPTIONS) &&
136 ValidateStripeManagedAccount(me, ADD_BANK_ACCOUNT_STATE) &&
137 ValidateStripeAccountLegalEntityOptions(me, ADD_STRIPE_ACCOUNT_LEGAL_ENTITY_OPTIONS_STATE);
138}
139
140export function ValidateStripeAccountBankAccountOptions(me, stripeState) {
141 var _validation = {
142 'accountNumber': validation(['notempty', 'numbers', 'length9to17']),
143 'bankName': validation(['notempty', 'alphanumericlike']),
144 'accountHolderName': validation(['notempty', 'alphanumericlike']),
145 'routingNumber': validation(['notempty', 'numbers', 'length9']),
146 }
147
148 var valid = validate(me, _validation, stripeState);
149 me.props.UI(LA.ADD_STRIPE_ACCOUNT_BANK_ACCOUNT_OPTIONS_VALID, valid);
150 me.props.UI(LA.ADD_STRIPE_ACCOUNT_BANK_ACCOUNT_OPTIONS, stripeState, true);
151 return valid;
152}
153
154function numbers(x) {
155 return !(x || '').toString().split('').find(t => {
156 return '0123456789'.indexOf(t) === -1;
157 });
158}
159
160function isntDependentAndHidden(prop, ui, obj) {
161
162 if (obj && ui.properties[prop].find(t => t.dependsOn)) {
163 var res = true;
164 ui.properties[prop].find(t => {
165 Object.keys(t.extensions || {}).map(key => {
166 if (t.extensions[key] &&
167 t.extensions[key].dependsOn &&
168 t.extensions[key].property &&
169 t.extensions[key].match &&
170 t.extensions[key].match.find(v => obj[t.extensions[key].property.lowercaseFirstLetter()] === v) === undefined) {
171 res = false;
172 }
173 })
174 });
175 return res;
176 }
177 return true;
178}
179
180export function validateUI(ui, obj) {
181 if (ui && ui.properties) {
182 var _validation = {};
183 for (var prop in ui.properties) {
184 var vrules = [];
185 (ui.properties[prop] || []).filter(t => {
186 return isntDependentAndHidden(prop, ui, obj);
187 }).map(t => {
188 vrules = [...vrules, ...(t.validationRules || [])];
189 })
190 if (vrules && vrules.length) {
191 var validationTexts = {};
192 ui.properties[prop].map(t => {
193 if (t) {
194 validationTexts = { ...validationTexts, ...t.validationTexts };
195 }
196 })
197 _validation[prop] = validation(vrules, { validationTexts });
198 }
199 }
200
201 var stripeState = obj;
202 var valid = validate(_validation, stripeState, (t, v) => {
203 return t[v];
204 });
205 return valid;
206 }
207}
208export function validation(args, opts) {
209 var { validationTexts } = (opts || {})
210 return args.map(x => {
211 var temp = (function () {
212 var validationText = (validationTexts || {})[x];
213 switch (x) {
214 case 'zipempty':
215 return {
216 func: x => !x || (x.length === 5 && numbers(x)),
217 message: validationText || Titles.ZipCodeInvalid
218 }
219
220 case 'zip':
221 return {
222 func: x => x.length === 5 && numbers(x),
223 message: validationText || Titles.ZipCodeInvalid
224 }
225 case 'pastdate':
226 case 'beforenow':
227 return {
228 func: v => {
229 try {
230 var date = new Date(Date.parse(v));
231 return Date.now() - date.getTime() > 0;
232 }
233 catch (e) { return false }
234 },
235 message: validationText || Titles.MustBeInThePast
236 }
237 case '18plus':
238 return {
239 func: v => {
240 try {
241 var date = new Date(Date.parse(v));
242 return Date.now() - date.getTime() > 5.676e+11;
243 }
244 catch (e) { return false }
245
246 },
247 message: validationText || Titles.MustBeAtLeast18
248 }
249 case 'expirationYear':
250 return {
251 func: (v, obj) => {
252 if (obj && opts && opts.month && opts.year) {
253 var date = new Date();
254 var month = date.getUTCMonth() + 1;
255 var year = date.getUTCFullYear();
256
257 if (year > parseFloat(obj[opts.year])) {
258 return false;
259 }
260 }
261 return true;
262 },
263 message: validationText || Titles.InvalidYear
264 }
265 case 'expirationMonth':
266 return {
267 func: (v, obj) => {
268 if (obj && opts && opts.month && opts.year) {
269 var date = new Date();
270 var month = date.getUTCMonth() + 1;
271 var year = date.getUTCFullYear();
272 if ((month > parseFloat(obj[opts.month])) && year === parseFloat(obj[opts.year])) {
273 return false;
274 }
275 if (year > parseFloat(obj[opts.year])) {
276 return false;
277 }
278 }
279 return true;
280 },
281 message: validationText || Titles.InvalidMonth
282 }
283 case 'email':
284 return {
285 func: v => validateEmail(v),
286 message: validationText || Titles.EnterValidEmail,
287 }
288 case 'maxlength22':
289 return {
290 func: x => x.length <= 22,
291 message: validationText || Titles.TooLong,
292 }
293 case 'length16':
294 return {
295 func: x => x.length === 16,
296 message: validationText || Titles.IncorrectLength,
297 }
298 case 'length14t19':
299 return {
300 func: x => x.length >= 14 && x.length <= 19,
301 message: validationText || Titles.IncorrectLength,
302 }
303 case 'credit':
304 return {
305 func: x => {
306 return CredCardValidations.find(j => {
307 return j.startsWith.find(t => x.startsWith(t)) && j.lengths.find(t => x.length == t);
308 })
309 },
310 message: validationText || Titles.InvalidCard
311 }
312 case 'length3':
313 return {
314 func: x => x.length === 3,
315 message: validationText || Titles.IncorrectLength,
316 }
317
318 case 'maxlength50':
319 return {
320 func: x => x.length <= 50,
321 message: validationText || Titles.TooLong,
322 }
323 case 'email_empty':
324 return {
325 func: v => !v || validateEmail(v),
326 message: validationText || Titles.EnterValidEmail,
327 }
328 case 'url':
329 return {
330 func: v => isUrlValid(v),
331 message: validationText || Titles.ValidUrl
332 }
333 case 'url_empty':
334 return {
335 func: v => !(v || '').toString().trim() || isUrlValid(v),
336 message: validationText || Titles.ValidUrl,
337 }
338 case 'notempty':
339 return {
340 func: v => {
341 if (Array.isArray(v)) {
342 return v.length;
343 }
344 return v
345 },
346 message: validationText || Titles.CantBeEmpty
347 };
348 case 'debit':
349 return {
350 func: v => {
351 var tests = {
352 'name': validation(['notempty', 'alphanumericlike', 'maxlength50']),
353 'number': validation(['notempty', 'length14t19', 'credit']),
354 'cvc': validation(['notempty', 'length3t4']),
355 'expirationYear': validation(['expirationYear'], {
356 year: 'expirationYear',
357 month: 'expirationMonth'
358 }),
359 'expirationMonth': validation(['expirationMonth'], {
360 year: 'expirationYear',
361 month: 'expirationMonth'
362 })
363 }
364 var res = validate(tests, v || {}, (x, y) => { return x ? x[y] : null });
365 return res.result;
366 },
367 message: validationText || Titles.DebitIncorrect
368 }
369 case 'year':
370 return {
371 func: x => !`${x}` || (x || '').length === 0 || (x.length === 4 && !(`${x}`.split('').findIndex(y => `0123456789`.indexOf(y) !== -1))),
372 message: validationText || Titles.YearInvalid
373 }
374 case 'cvc':
375 return {
376 func: x => x.length >= 3 && x.length <= 4,
377 message: validationText || Titles.Length3t4
378 }
379 case 'length3t4':
380 return {
381 func: x => x.length >= 3 && x.length <= 4,
382 message: validationText || Titles.Length3t4
383 }
384
385 case 'length12':
386 return {
387 func: x => x.length === 12,
388 message: validationText || Titles.Length12
389 }
390 case 'socialsecurity':
391 return {
392 func: x => x && x.length === 9,
393 message: validationText || Titles.InvalidSS
394 }
395 case 'length9to17':
396 return {
397 func: x =>
398 x.length === 12 ||
399 x.length === 13 ||
400 x.length === 14 ||
401 x.length === 15 ||
402 x.length === 16 ||
403 x.length === 17 ||
404 x.length === 11 ||
405 x.length === 10 ||
406 x.length === 9,
407 message: validationText || Titles.Length9to17
408 }
409 case 'length8':
410 return {
411 func: x => x.length === 8,
412 message: validationText || Titles.Length8
413 }
414 case 'length9':
415 return {
416 func: x => x.length === 9,
417 message: validationText || Titles.Length9
418 };
419 case 'length4':
420 return {
421 func: x => x.length === 4,
422 message: validationText || Titles.Length4
423 }
424 case 'length5':
425 return {
426 func: x => x.length === 5,
427 message: validationText || Titles.Length5
428 }
429 case 'numeric':
430 case 'numbers':
431 return {
432 func: numbers,
433 message: validationText || Titles.OnlyNumbersAllowed
434 };
435 case 'alphanumericlike':
436 return {
437 func: x => !(x || '').toString().split('').find(t => {
438 t = t.toLowerCase();
439 return 'abcdefghijk lmnopqrstuvwxyz,.;\'0123456789'.indexOf(t) === -1;
440 }),
441 message: validationText || Titles.ValidCharacters
442 };
443 }
444 })();
445 if (temp) {
446 Object.assign(temp, { name: x });
447 }
448 return temp;
449 });
450}
451export function GetCardType(x) {
452 return CredCardValidations.find(j => {
453 return j.startsWith.find(t => x.startsWith(t)) && j.lengths.find(t => x.length == t);
454 });
455}
456
457const CredCardValidations = [
458 { name: 'American Express', startsWith: ['34', '37'], lengths: [15] },
459 { name: 'Diners Club - Carte Blanche', startsWith: ['300', '301', '302', '303', '304', '305'], lengths: [14] },
460 { name: 'Diners Club - International', startsWith: ['36'], lengths: [14] },
461 { name: 'Diners Club - USA & Canada', startsWith: ['54'], lengths: [16] },
462 { name: 'Discover', startsWith: [...[].interpolate(622126, 622925 + 1, x => x).map(x => x.toString()), ...['6011', '644', '645', '646', '647', '648', '649', '65']], lengths: [16, 17, 18, 19] },
463 { name: 'InstaPayment', startsWith: [...[637, 638, 639].map(x => x.toString())], lengths: [16] },
464 { name: 'JCB', startsWith: [...[].interpolate(3528, 3589 + 1, x => x).map(x => x.toString())], lengths: [16, 17, 18, 19] },
465 { name: 'Maestro', startsWith: [...[5018, 5020, 5038, 5893, 6304, 6759, 6761, 6762, 6763].map(x => x.toString())], lengths: [16, 17, 18, 19] },
466 { name: 'MasterCard', startsWith: [...[].interpolate(222100, 272099 + 1, x => x.toString()), ...[51, 52, 53, 54, 55].map(x => x.toString())], lengths: [16, 17, 18, 19] },
467 { name: 'Visa', startsWith: [...[4].map(x => x.toString())], lengths: [16, 13, 19] },
468 { name: 'Visa Electron', startsWith: [...[4026, 417500, 4508, 4844, 4913, 4917].map(x => x.toString())], lengths: [16] }];
469
470export function InputField(value, iconName, dark) {
471 return {
472 errorIcon: () => {
473 if (value) {
474 return <Icon name='md-flag' style={{ color: Colors.Color5 }} />
475 }
476 if (iconName)
477 return <Icon name={iconName} style={{ color: Colors.Color5 }} />;
478 return null;
479 },
480 errorText: () => {
481 var text = value;
482 if (text) {
483 return Common.ErrorText(text);
484 }
485 return null;
486 },
487 };
488}
489function validateEmail(email) {
490 var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
491 return re.test(email);
492}
493
494function isUrlValid(userInput) {
495 var res = userInput.match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g);
496 if (res == null)
497 return false;
498 else
499 return true;
500}
501export function validate(validation, stripeState, getValue) {
502 var result = { result: true };
503 var validationState = {};
504 for (var key in validation) {
505 var rules = validation[key];
506 var _rule = null;
507 if (rules.find(rule => {
508 if (!stripeState) {
509 return true;
510 }
511 var _validationStateValue = getValue(stripeState, key);
512 if (stripeState.hasOwnProperty(key) && !rule.func(_validationStateValue, stripeState)) {
513 _rule = rule;
514 return true;
515 }
516 return false;
517 })) {
518 validationState = Object.assign(validationState, { [key]: _rule ? _rule.message : Titles.Required })
519 result.result = false;
520 }
521 else {
522 validationState = Object.assign(validationState, { [key]: false })
523 }
524 }
525 result.validationState = validationState;
526 return result;
527}
\No newline at end of file