-
Notifications
You must be signed in to change notification settings - Fork 134
/
request-phone-code.ts
102 lines (89 loc) · 2.67 KB
/
request-phone-code.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import { getTestAccounts, getTwilioConfig } from "@config"
import { TestAccountsChecker } from "@domain/accounts/test-accounts-checker"
import { NotImplementedError } from "@domain/errors"
import { RateLimitConfig } from "@domain/rate-limit"
import { RateLimiterExceededError } from "@domain/rate-limit/errors"
import { consumeLimiter } from "@services/rate-limit"
import { TwilioClient } from "@services/twilio"
export const requestPhoneCodeWithCaptcha = async ({
phone,
geetest,
geetestChallenge,
geetestValidate,
geetestSeccode,
logger,
ip,
}: {
phone: PhoneNumber
geetest: GeetestType
geetestChallenge: string
geetestValidate: string
geetestSeccode: string
logger: Logger
ip: IpAddress
}): Promise<true | ApplicationError> => {
logger.info({ phone, ip }, "RequestPhoneCodeGeetest called")
const verifySuccess = await geetest.validate(
geetestChallenge,
geetestValidate,
geetestSeccode,
)
if (verifySuccess instanceof Error) return verifySuccess
return requestPhoneCode({
phone,
logger,
ip,
})
}
export const requestPhoneCode = async ({
phone,
logger,
ip,
}: {
phone: PhoneNumber
logger: Logger
ip: IpAddress
}): Promise<true | PhoneProviderServiceError> => {
logger.info({ phone, ip }, "RequestPhoneCode called")
{
const limitOk = await checkPhoneCodeAttemptPerIpLimits(ip)
if (limitOk instanceof Error) return limitOk
}
{
const limitOk = await checkPhoneCodeAttemptPerPhoneLimits(phone)
if (limitOk instanceof Error) return limitOk
}
{
const limitOk = await checkPhoneCodeAttemptPerPhoneMinIntervalLimits(phone)
if (limitOk instanceof Error) return limitOk
}
const testAccounts = getTestAccounts()
if (TestAccountsChecker(testAccounts).isPhoneValid(phone)) {
return true
}
if (getTwilioConfig().accountSid === "AC_twilio_id") {
return new NotImplementedError("use test account for local dev and tests")
}
return TwilioClient().initiateVerify(phone)
}
const checkPhoneCodeAttemptPerIpLimits = async (
ip: IpAddress,
): Promise<true | RateLimiterExceededError> =>
consumeLimiter({
rateLimitConfig: RateLimitConfig.requestPhoneCodeAttemptPerIp,
keyToConsume: ip,
})
const checkPhoneCodeAttemptPerPhoneLimits = async (
phone: PhoneNumber,
): Promise<true | RateLimiterExceededError> =>
consumeLimiter({
rateLimitConfig: RateLimitConfig.requestPhoneCodeAttemptPerPhone,
keyToConsume: phone,
})
const checkPhoneCodeAttemptPerPhoneMinIntervalLimits = async (
phone: PhoneNumber,
): Promise<true | RateLimiterExceededError> =>
consumeLimiter({
rateLimitConfig: RateLimitConfig.requestPhoneCodeAttemptPerPhoneMinInterval,
keyToConsume: phone,
})