on 6605d99 help sign in
bridge/src/lib/validators.js
194 lines 4.7 kB history raw
1import * as bip39 from 'bip39';
2import * as ob from 'urbit-ob';
3import { identity } from 'lodash';
5import { isValidAddress } from './wallet';
6import patp2dec from './patp2dec';
8// via: https://emailregex.com/
9const emailRegExp = /^(([^<>()[\]\\.,;:\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,}))$/;
11// is this 64 hex chars?
12const hexRegExp = /[0-9A-Fa-f]{64}/g;
14// Wraps single validation functions in a controlled and predictable way.
15export const simpleValidatorWrapper = ({
16 prevMessage,
17 transform = identity,
18 validator,
19 error,
20}) => {
21 // If a previous validation has already failed, skip this validation and
22 // return the prev message to the next stage in the validation function chain.
23 // Failed validations should drop all the way down the chain and drop out of
24 // the output.
25 if (!prevMessage.pass) {
26 return prevMessage;
27 }
29 // Run the validator and return the result.
30 const pass = validator(prevMessage.data);
31 const data = pass ? transform(prevMessage.data) : prevMessage.data;
33 return newMessage(data, pass, !pass && error);
34};
36// Validation message
37// {
38// data: ...
39// pass: ...
40// error: ...
41// }
42// Creates a new validation message in a uniform way.
43const newMessage = (data, pass, error) => ({
44 // The input data
45 data,
46 // Has the data passed validation?
47 pass,
48 // If data has failed a validator, the error message goes here.
49 error,
50});
52// A validator that always passes.
53export const kDefaultValidator = data => newMessage(data, true, null);
55// Validates a bip39 mnemonic
56export const validateMnemonic = m =>
57 simpleValidatorWrapper({
58 prevMessage: m,
59 validator: d => bip39.validateMnemonic(d),
60 error: 'This is not a valid mnemonic.',
61 });
63// Checks an empty field
64export const validateNotEmpty = m =>
65 simpleValidatorWrapper({
66 prevMessage: m,
67 validator: d => {
68 try {
69 return d.length > 1;
70 } catch {
71 return false;
72 }
73 },
74 error: 'This field is required.',
75 });
77// Checks if a patp is a valid galaxy
78export const validateGalaxy = m =>
79 simpleValidatorWrapper({
80 prevMessage: m,
81 validator: d => {
82 let point;
83 try {
84 point = patp2dec(d);
85 return point >= 0 && point < 256;
86 } catch (e) {
87 return false;
88 }
89 },
90 error: 'This is not a valid galaxy',
91 });
93export const validatePoint = m =>
94 simpleValidatorWrapper({
95 prevMessage: m,
96 validator: d => {
97 try {
98 return ob.isValidPatp(d);
99 } catch (e) {
100 return false;
101 }
102 },
103 error: 'This is not a valid point',
104 });
106export const validateTicket = m =>
107 simpleValidatorWrapper({
108 prevMessage: m,
109 validator: d => {
110 try {
111 return ob.isValidPatq(d);
112 } catch (e) {
113 return false;
114 }
115 },
116 error: 'This is not a valid ticket',
117 });
119export const validateShard = m =>
120 simpleValidatorWrapper({
121 prevMessage: m,
122 validator: d => {
123 try {
124 return ob.isValidPatq(d);
125 } catch (e) {
126 return false;
127 }
128 },
129 error: 'This is not a valid shard',
130 });
132export const validateLength = (m, l) =>
133 simpleValidatorWrapper({
134 prevMessage: m,
135 validator: d => {
136 try {
137 return d.length === l;
138 } catch {
139 return false;
140 }
141 },
142 error: 'This is of an invalid length',
143 });
145export const validateNetworkKey = m =>
146 simpleValidatorWrapper({
147 prevMessage: m,
148 validator: d => hexRegExp.test(d),
149 error: 'This is not a valid network key',
150 });
152export const validateNetworkSeed = m =>
153 simpleValidatorWrapper({
154 prevMessage: m,
155 validator: d => hexRegExp.test(d),
156 error: 'This is not a valid network seed',
157 });
159// Checks if a string is a valid ethereum address
160export const validateEthereumAddress = m =>
161 simpleValidatorWrapper({
162 prevMessage: m,
163 validator: d => isValidAddress(d),
164 error: 'This is not a valid Ethereum address',
165 });
167export const validateEmail = m =>
168 simpleValidatorWrapper({
169 prevMessage: m,
170 validator: d => emailRegExp.test(d),
171 error: 'This is not a valid email address',
172 });
174export const validateInt = m =>
175 simpleValidatorWrapper({
176 prevMessage: m,
177 transform: d => parseInt(d, 10),
178 validator: d => {
179 try {
180 parseInt(d, 10);
181 return;
182 } catch {
183 return false;
184 }
185 },
186 error: 'This is not a valid number',
187 });
189export const validateExactly = (value, error) => m =>
190 simpleValidatorWrapper({
191 prevMessage: m,
192 validator: d => d === value,
193 error,
194 });