@driveflux/api-functions 1.0.135 → 1.0.136
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/dist/auth/confirm.js +24 -24
- package/dist/auth/consent.js +22 -27
- package/dist/auth/emails.js +12 -13
- package/dist/auth/formatter.js +5 -5
- package/dist/auth/otp.js +66 -50
- package/dist/auth/register.js +48 -35
- package/dist/auth/tokens.js +58 -55
- package/dist/auth/verifications.js +53 -52
- package/dist/constants.js +0 -1
- package/dist/create-logger.js +1 -2
- package/dist/mailjet/calls/manage-contacts-in-list.js +5 -6
- package/dist/mailjet/calls/manage-subscription-status.js +4 -5
- package/dist/mailjet/calls/request-service.js +7 -6
- package/dist/mailjet/refresh-email-preferences.js +11 -12
- package/dist/mailjet/set-contact.js +11 -12
- package/dist/mailjet/types.js +1 -2
- package/dist/mailjet/utils/convert-to-array.js +8 -6
- package/dist/mailjet/utils/extract-email-preferences.js +14 -15
- package/dist/mailjet/utils/lists.js +7 -8
- package/dist/mailjet/utils/update-email-references.js +16 -15
- package/dist/notion/client.js +22 -19
- package/dist/notion/helpful.js +6 -9
- package/dist/notion/schemas/block.js +42 -48
- package/dist/notion/schemas/common.js +9 -14
- package/dist/notion/schemas/database.js +62 -60
- package/dist/notion/schemas/emoji.js +1 -2
- package/dist/notion/schemas/file.js +9 -9
- package/dist/notion/schemas/kb.js +5 -6
- package/dist/notion/schemas/page.js +72 -61
- package/dist/notion/schemas/parent.js +4 -5
- package/dist/notion/schemas/user.js +18 -19
- package/dist/reservation/agree.js +2 -3
- package/dist/reservation/checks.js +3 -4
- package/dist/reservation/display-vehicle.js +73 -83
- package/dist/reservation/ensure-user-billing-address.js +9 -11
- package/dist/reservation/fetch-or-create.js +49 -56
- package/dist/reservation/invoice.js +77 -88
- package/dist/reservation/payer.js +5 -6
- package/dist/reservation/payment-intent-sync.js +4 -6
- package/dist/reservation/reserve.js +3 -4
- package/dist/reservation/types.js +1 -2
- package/dist/reservation/vehicle.js +13 -16
- package/dist/slack.js +24 -29
- package/dist/validation.js +77 -79
- package/dist/vehicle/vehicle-pricing/constants.js +22 -19
- package/dist/vehicle/vehicle-pricing/index.js +28 -42
- package/dist/vehicle/vehicle-pricing/types.js +1 -2
- package/package.json +2 -2
package/dist/auth/tokens.js
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
import { prisma } from '@driveflux/db';
|
|
2
2
|
import { generateId } from '@driveflux/db/id';
|
|
3
|
-
import { makeProblem, PROBLEM_CORRUPT, PROBLEM_EXPIRED, PROBLEM_INVALID_DATA, PROBLEM_NOT_FOUND
|
|
3
|
+
import { makeProblem, PROBLEM_CORRUPT, PROBLEM_EXPIRED, PROBLEM_INVALID_DATA, PROBLEM_NOT_FOUND } from '@driveflux/problem';
|
|
4
4
|
import { Err, Ok } from '@driveflux/result';
|
|
5
5
|
import { addDays } from 'date-fns/addDays';
|
|
6
6
|
import { addMinutes } from 'date-fns/addMinutes';
|
|
7
7
|
import { customAlphabet } from 'nanoid';
|
|
8
|
-
export const createToken = async (userId, type, value, providedExpiresAt)
|
|
8
|
+
export const createToken = async (userId, type, value, providedExpiresAt)=>{
|
|
9
9
|
// Generate 6 digits
|
|
10
10
|
const alphabet = '0123456789';
|
|
11
11
|
const nanoid = customAlphabet(alphabet, 6);
|
|
12
12
|
const identifier = !userId ? value : null;
|
|
13
13
|
const scope = type === 'email' ? 'verify-email' : 'verify-phone';
|
|
14
|
-
const expiresAt = providedExpiresAt ||
|
|
15
|
-
(type === 'email' ? addDays(new Date(), 1) : addMinutes(new Date(), 30));
|
|
14
|
+
const expiresAt = providedExpiresAt || (type === 'email' ? addDays(new Date(), 1) : addMinutes(new Date(), 30));
|
|
16
15
|
if (!userId && !identifier) {
|
|
17
16
|
return;
|
|
18
17
|
}
|
|
@@ -20,72 +19,69 @@ export const createToken = async (userId, type, value, providedExpiresAt) => {
|
|
|
20
19
|
data: {
|
|
21
20
|
id: generateId('Token'),
|
|
22
21
|
value: nanoid(),
|
|
23
|
-
...
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
},
|
|
29
|
-
},
|
|
22
|
+
...userId ? {
|
|
23
|
+
user: {
|
|
24
|
+
connect: {
|
|
25
|
+
id: userId
|
|
26
|
+
}
|
|
30
27
|
}
|
|
31
|
-
|
|
32
|
-
...
|
|
28
|
+
} : {},
|
|
29
|
+
...identifier ? {
|
|
30
|
+
identifier
|
|
31
|
+
} : {},
|
|
33
32
|
expiresAt,
|
|
34
33
|
scope,
|
|
35
34
|
metadata: {
|
|
36
|
-
[type]: value
|
|
37
|
-
}
|
|
38
|
-
}
|
|
35
|
+
[type]: value
|
|
36
|
+
}
|
|
37
|
+
}
|
|
39
38
|
});
|
|
40
39
|
};
|
|
41
|
-
export const createEmailToken = async (userId, email)
|
|
40
|
+
export const createEmailToken = async (userId, email)=>{
|
|
42
41
|
return await createToken(userId, 'email', email);
|
|
43
42
|
};
|
|
44
|
-
export const createSMSToken = async (userId, phoneNumber)
|
|
43
|
+
export const createSMSToken = async (userId, phoneNumber)=>{
|
|
45
44
|
return await createToken(userId, 'phoneNumber', phoneNumber);
|
|
46
45
|
};
|
|
47
|
-
export const verifyToken = async (tokenIdOrValue, verifications, option)
|
|
48
|
-
const token = typeof tokenIdOrValue === 'object'
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
46
|
+
export const verifyToken = async (tokenIdOrValue, verifications, option)=>{
|
|
47
|
+
const token = typeof tokenIdOrValue === 'object' ? tokenIdOrValue : await prisma.token.findFirst({
|
|
48
|
+
where: {
|
|
49
|
+
OR: [
|
|
50
|
+
{
|
|
51
|
+
id: tokenIdOrValue
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
value: tokenIdOrValue
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
},
|
|
58
|
+
...option?.includeUser ? {
|
|
59
|
+
include: {
|
|
60
|
+
user: true
|
|
61
|
+
}
|
|
62
|
+
} : {}
|
|
63
|
+
});
|
|
56
64
|
if (!token) {
|
|
57
65
|
return new Err(makeProblem(PROBLEM_NOT_FOUND, 'Token not found'));
|
|
58
66
|
}
|
|
59
67
|
if (token.expiresAt && token.expiresAt.getTime() < Date.now()) {
|
|
60
68
|
return new Err(makeProblem(PROBLEM_EXPIRED, 'This token has expired'));
|
|
61
69
|
}
|
|
62
|
-
if (typeof verifications?.scope !== 'undefined' &&
|
|
63
|
-
token.scope !== verifications.scope) {
|
|
70
|
+
if (typeof verifications?.scope !== 'undefined' && token.scope !== verifications.scope) {
|
|
64
71
|
return new Err(makeProblem(PROBLEM_INVALID_DATA, 'Invalid token scope'));
|
|
65
72
|
}
|
|
66
73
|
if (typeof verifications?.metadata !== 'undefined') {
|
|
67
74
|
if (typeof verifications.metadata.phoneNumber !== 'undefined') {
|
|
68
|
-
const tokenPhoneNumber = token?.metadata &&
|
|
69
|
-
|
|
70
|
-
'phoneNumber' in token.metadata
|
|
71
|
-
? token.metadata.phoneNumber
|
|
72
|
-
: undefined;
|
|
73
|
-
const formattedTokenPhoneNumber = `+${(tokenPhoneNumber)?.replace(/[^0-9]/g, '')}`;
|
|
75
|
+
const tokenPhoneNumber = token?.metadata && typeof token.metadata === 'object' && 'phoneNumber' in token.metadata ? token.metadata.phoneNumber : undefined;
|
|
76
|
+
const formattedTokenPhoneNumber = `+${tokenPhoneNumber?.replace(/[^0-9]/g, '')}`;
|
|
74
77
|
const phoneNumber = verifications.metadata?.phoneNumber;
|
|
75
|
-
if (verifications.scope === 'verify-phone' &&
|
|
76
|
-
phoneNumber !== formattedTokenPhoneNumber &&
|
|
77
|
-
phoneNumber !== tokenPhoneNumber) {
|
|
78
|
+
if (verifications.scope === 'verify-phone' && phoneNumber !== formattedTokenPhoneNumber && phoneNumber !== tokenPhoneNumber) {
|
|
78
79
|
return new Err(makeProblem(PROBLEM_INVALID_DATA, 'Invalid token data'));
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
82
|
if (typeof verifications.metadata.email !== 'undefined') {
|
|
82
|
-
const tokenEmail = token?.metadata &&
|
|
83
|
-
|
|
84
|
-
'email' in token.metadata
|
|
85
|
-
? token.metadata.email
|
|
86
|
-
: undefined;
|
|
87
|
-
if (verifications.scope === 'verify-email' &&
|
|
88
|
-
tokenEmail !== verifications.metadata.email) {
|
|
83
|
+
const tokenEmail = token?.metadata && typeof token.metadata === 'object' && 'email' in token.metadata ? token.metadata.email : undefined;
|
|
84
|
+
if (verifications.scope === 'verify-email' && tokenEmail !== verifications.metadata.email) {
|
|
89
85
|
return new Err(makeProblem(PROBLEM_INVALID_DATA, 'Invalid token data'));
|
|
90
86
|
}
|
|
91
87
|
}
|
|
@@ -107,23 +103,30 @@ export const verifyToken = async (tokenIdOrValue, verifications, option) => {
|
|
|
107
103
|
}
|
|
108
104
|
return new Ok(token);
|
|
109
105
|
};
|
|
110
|
-
export const clearToken = async (tokenId)
|
|
106
|
+
export const clearToken = async (tokenId)=>{
|
|
111
107
|
try {
|
|
112
108
|
await prisma.token.delete({
|
|
113
109
|
where: {
|
|
114
|
-
id: tokenId
|
|
115
|
-
}
|
|
110
|
+
id: tokenId
|
|
111
|
+
}
|
|
116
112
|
});
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Nothing to for now
|
|
113
|
+
} catch (_e) {
|
|
114
|
+
// Nothing to for now
|
|
120
115
|
}
|
|
121
116
|
};
|
|
122
|
-
export const clearExpiredTokens = async ()
|
|
117
|
+
export const clearExpiredTokens = async ()=>{
|
|
123
118
|
await prisma.token.deleteMany({
|
|
124
119
|
where: {
|
|
125
|
-
OR: [
|
|
126
|
-
|
|
120
|
+
OR: [
|
|
121
|
+
{
|
|
122
|
+
expiresAt: {
|
|
123
|
+
lte: new Date()
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
invalid: true
|
|
128
|
+
}
|
|
129
|
+
]
|
|
130
|
+
}
|
|
127
131
|
});
|
|
128
132
|
};
|
|
129
|
-
//# sourceMappingURL=tokens.js.map
|
|
@@ -3,19 +3,21 @@ import { prisma } from '@driveflux/db';
|
|
|
3
3
|
import { send } from '@driveflux/email';
|
|
4
4
|
import { verificationEmail } from '@driveflux/email-templates/flux/verification';
|
|
5
5
|
import { enhancedFetch } from '@driveflux/fetch';
|
|
6
|
-
import { makeProblem, PROBLEM_CONFLICT, PROBLEM_EXTERNAL, PROBLEM_INTERNAL, PROBLEM_INVALID_DATA, PROBLEM_NOT_FOUND, PROBLEM_NOT_IMPLEMENTED
|
|
6
|
+
import { makeProblem, PROBLEM_CONFLICT, PROBLEM_EXTERNAL, PROBLEM_INTERNAL, PROBLEM_INVALID_DATA, PROBLEM_NOT_FOUND, PROBLEM_NOT_IMPLEMENTED } from '@driveflux/problem';
|
|
7
7
|
import { reportProblem } from '@driveflux/reporter';
|
|
8
8
|
import { Err, Ok } from '@driveflux/result';
|
|
9
9
|
import { z } from 'zod';
|
|
10
10
|
import { clearToken, createEmailToken, createSMSToken } from './tokens.js';
|
|
11
11
|
const CheckDuplicationBody = z.object({
|
|
12
12
|
phoneNumber: z.string(),
|
|
13
|
-
email: z.string().transform((email)
|
|
13
|
+
email: z.string().transform((email)=>email.toLowerCase().trim())
|
|
14
14
|
});
|
|
15
|
-
export const sendVerificationEmail = async (userId, temporaryEmail, next)
|
|
16
|
-
const user = typeof userId === 'string'
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
export const sendVerificationEmail = async (userId, temporaryEmail, next)=>{
|
|
16
|
+
const user = typeof userId === 'string' ? await prisma.user.findUnique({
|
|
17
|
+
where: {
|
|
18
|
+
id: userId
|
|
19
|
+
}
|
|
20
|
+
}) : userId;
|
|
19
21
|
if (!user) {
|
|
20
22
|
return new Err(makeProblem(PROBLEM_NOT_FOUND, `User ${typeof userId === 'string' ? userId : 'unknown'} not found.`));
|
|
21
23
|
}
|
|
@@ -32,18 +34,18 @@ export const sendVerificationEmail = async (userId, temporaryEmail, next) => {
|
|
|
32
34
|
}
|
|
33
35
|
const updatedUser = await prisma.user.update({
|
|
34
36
|
where: {
|
|
35
|
-
id: user.id
|
|
37
|
+
id: user.id
|
|
36
38
|
},
|
|
37
39
|
data: {
|
|
38
|
-
temporaryEmail: destinationEmail
|
|
40
|
+
temporaryEmail: destinationEmail
|
|
39
41
|
},
|
|
40
42
|
include: {
|
|
41
|
-
tokens: true
|
|
42
|
-
}
|
|
43
|
+
tokens: true
|
|
44
|
+
}
|
|
43
45
|
});
|
|
44
46
|
const tokens = updatedUser?.tokens;
|
|
45
47
|
if (tokens) {
|
|
46
|
-
await Promise.allSettled(tokens.map(async (userToken)
|
|
48
|
+
await Promise.allSettled(tokens.map(async (userToken)=>{
|
|
47
49
|
if (userToken.scope === 'verify-email' && userToken.id !== token.id) {
|
|
48
50
|
return await clearToken(userToken.id);
|
|
49
51
|
}
|
|
@@ -54,15 +56,13 @@ export const sendVerificationEmail = async (userId, temporaryEmail, next) => {
|
|
|
54
56
|
const query = new URLSearchParams({
|
|
55
57
|
email: destinationEmail,
|
|
56
58
|
token: token.id,
|
|
57
|
-
code: token.value
|
|
59
|
+
code: token.value
|
|
58
60
|
});
|
|
59
61
|
if (next) {
|
|
60
62
|
query.append('next', next);
|
|
61
63
|
}
|
|
62
64
|
const link = `${config.appUrl}/verify?${query}`;
|
|
63
|
-
const title = temporaryEmail
|
|
64
|
-
? 'Confirm email change'
|
|
65
|
-
: 'Verify your email address';
|
|
65
|
+
const title = temporaryEmail ? 'Confirm email change' : 'Verify your email address';
|
|
66
66
|
try {
|
|
67
67
|
// Generate html
|
|
68
68
|
const html = verificationEmail({
|
|
@@ -70,119 +70,122 @@ export const sendVerificationEmail = async (userId, temporaryEmail, next) => {
|
|
|
70
70
|
link,
|
|
71
71
|
title: `${title}`,
|
|
72
72
|
newEmail: temporaryEmail,
|
|
73
|
-
isChanging: !!temporaryEmail
|
|
73
|
+
isChanging: !!temporaryEmail
|
|
74
74
|
});
|
|
75
75
|
// send email
|
|
76
76
|
const result = await send({
|
|
77
77
|
to: {
|
|
78
78
|
name: user.firstName || '',
|
|
79
|
-
address: destinationEmail
|
|
79
|
+
address: destinationEmail
|
|
80
80
|
},
|
|
81
81
|
subject: `${title}`,
|
|
82
|
-
html
|
|
82
|
+
html
|
|
83
83
|
});
|
|
84
84
|
if (result.err) {
|
|
85
85
|
console.error('Error sending email:', result.val);
|
|
86
86
|
return new Err(makeProblem('email_not_sent', 'Unable to send the verification email'));
|
|
87
87
|
}
|
|
88
|
-
return new Ok({
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
return new Ok({
|
|
89
|
+
success: true,
|
|
90
|
+
link
|
|
91
|
+
});
|
|
92
|
+
} catch (e) {
|
|
91
93
|
return new Err(makeProblem('email_not_sent', e.message));
|
|
92
94
|
}
|
|
93
95
|
};
|
|
94
|
-
export const verifyEmailUsage = async (newEmail)
|
|
96
|
+
export const verifyEmailUsage = async (newEmail)=>{
|
|
95
97
|
// TODO: add email regex checking
|
|
96
98
|
if (newEmail.length < 3) {
|
|
97
99
|
return new Err(makeProblem(PROBLEM_INVALID_DATA, 'Email address needs minimum 3 characters'));
|
|
98
100
|
}
|
|
99
101
|
const existingEmail = await prisma.user.findFirst({
|
|
100
102
|
where: {
|
|
101
|
-
email: newEmail
|
|
102
|
-
}
|
|
103
|
+
email: newEmail
|
|
104
|
+
}
|
|
103
105
|
});
|
|
104
106
|
if (existingEmail) {
|
|
105
107
|
return new Err(makeProblem(PROBLEM_INVALID_DATA, 'The email address is already in use'));
|
|
106
108
|
}
|
|
107
109
|
return new Ok({});
|
|
108
110
|
};
|
|
109
|
-
export const sendVerificationSMS = async (userId, phoneNumber)
|
|
111
|
+
export const sendVerificationSMS = async (userId, phoneNumber)=>{
|
|
110
112
|
const token = await createSMSToken(userId, phoneNumber);
|
|
111
113
|
if (!token) {
|
|
112
114
|
return new Err(makeProblem(PROBLEM_NOT_IMPLEMENTED, 'Token was not created'));
|
|
113
115
|
}
|
|
114
116
|
return await sendSms(phoneNumber, token.value);
|
|
115
117
|
};
|
|
116
|
-
const formatPhoneNumber = (phoneNumber)
|
|
118
|
+
const formatPhoneNumber = (phoneNumber)=>{
|
|
117
119
|
return phoneNumber.replace(/[^0-9]/g, '');
|
|
118
120
|
};
|
|
119
|
-
const sendSms = async (phoneNumber, code)
|
|
121
|
+
const sendSms = async (phoneNumber, code)=>{
|
|
120
122
|
const isInternational = !formatPhoneNumber(phoneNumber).startsWith('60');
|
|
121
123
|
try {
|
|
122
|
-
const sendSmsResult = isInternational
|
|
123
|
-
? await sendVonageSms(phoneNumber, code)
|
|
124
|
-
: await sendEsmsSms(phoneNumber, code);
|
|
124
|
+
const sendSmsResult = isInternational ? await sendVonageSms(phoneNumber, code) : await sendEsmsSms(phoneNumber, code);
|
|
125
125
|
if (sendSmsResult.err) {
|
|
126
126
|
return new Err(await reportProblem(makeProblem({
|
|
127
127
|
type: 'public',
|
|
128
128
|
code: PROBLEM_EXTERNAL,
|
|
129
129
|
message: 'Unable to send sms verification',
|
|
130
130
|
privateMetadata: {
|
|
131
|
-
error: sendSmsResult.val
|
|
132
|
-
}
|
|
131
|
+
error: sendSmsResult.val
|
|
132
|
+
}
|
|
133
133
|
})));
|
|
134
134
|
}
|
|
135
|
-
return new Ok({
|
|
136
|
-
|
|
137
|
-
|
|
135
|
+
return new Ok({
|
|
136
|
+
success: true,
|
|
137
|
+
code
|
|
138
|
+
});
|
|
139
|
+
} catch (e) {
|
|
138
140
|
return new Err(await reportProblem(makeProblem({
|
|
139
141
|
type: 'public',
|
|
140
142
|
code: PROBLEM_INTERNAL,
|
|
141
143
|
message: 'Unable to send sms verification',
|
|
142
144
|
privateMetadata: {
|
|
143
|
-
error: e
|
|
144
|
-
}
|
|
145
|
+
error: e
|
|
146
|
+
}
|
|
145
147
|
})));
|
|
146
148
|
}
|
|
147
149
|
};
|
|
148
|
-
export const handleCheckDuplication = async (b)
|
|
150
|
+
export const handleCheckDuplication = async (b)=>{
|
|
149
151
|
const { phoneNumber, email } = CheckDuplicationBody.parse(b);
|
|
150
152
|
// Check if the user exists
|
|
151
153
|
const checkForEmail = await prisma.user.findFirst({
|
|
152
154
|
where: {
|
|
153
|
-
email: email.toLowerCase().trim()
|
|
154
|
-
}
|
|
155
|
+
email: email.toLowerCase().trim()
|
|
156
|
+
}
|
|
155
157
|
});
|
|
156
158
|
if (checkForEmail) {
|
|
157
159
|
return new Err(makeProblem(PROBLEM_CONFLICT, 'This email is already registered. Are you trying to sign in?'));
|
|
158
160
|
}
|
|
159
161
|
const checkForMobile = await prisma.user.findFirst({
|
|
160
162
|
where: {
|
|
161
|
-
phoneNumber: phoneNumber.replace(/[\s-]/g, '')
|
|
162
|
-
}
|
|
163
|
+
phoneNumber: phoneNumber.replace(/[\s-]/g, '')
|
|
164
|
+
}
|
|
163
165
|
});
|
|
164
166
|
if (checkForMobile) {
|
|
165
167
|
return new Err(makeProblem(PROBLEM_CONFLICT, 'The phone number is already in use. Please try a different one.'));
|
|
166
168
|
}
|
|
167
|
-
return new Ok({
|
|
169
|
+
return new Ok({
|
|
170
|
+
notDuplicate: true
|
|
171
|
+
});
|
|
168
172
|
};
|
|
169
173
|
/**
|
|
170
174
|
* This function runs only for foreign numbers and sends an SMS containing the OTP code to the foreign number
|
|
171
175
|
* @param phoneNumber user's phone number
|
|
172
176
|
* @param code OTP code
|
|
173
177
|
* @returns result of sending SMS to user
|
|
174
|
-
*/
|
|
175
|
-
const sendVonageSms = async (phoneNumber, code) => {
|
|
178
|
+
*/ const sendVonageSms = async (phoneNumber, code)=>{
|
|
176
179
|
const body = {
|
|
177
180
|
from: 'FLUX',
|
|
178
181
|
to: formatPhoneNumber(phoneNumber),
|
|
179
182
|
text: `FLUX verification code: ${code}`,
|
|
180
183
|
api_key: config.vonage.apiKey,
|
|
181
|
-
api_secret: config.vonage.apiSecret
|
|
184
|
+
api_secret: config.vonage.apiSecret
|
|
182
185
|
};
|
|
183
186
|
const result = await enhancedFetch('https://rest.nexmo.com/sms/json', {
|
|
184
187
|
method: 'POST',
|
|
185
|
-
body: JSON.stringify(body)
|
|
188
|
+
body: JSON.stringify(body)
|
|
186
189
|
});
|
|
187
190
|
return result;
|
|
188
191
|
};
|
|
@@ -191,19 +194,17 @@ const sendVonageSms = async (phoneNumber, code) => {
|
|
|
191
194
|
* @param phoneNumber user's phone number
|
|
192
195
|
* @param code OTP code
|
|
193
196
|
* @returns result of sending SMS to user
|
|
194
|
-
*/
|
|
195
|
-
const sendEsmsSms = async (phoneNumber, code) => {
|
|
197
|
+
*/ const sendEsmsSms = async (phoneNumber, code)=>{
|
|
196
198
|
const body = {
|
|
197
199
|
user: config.esms.apiKey,
|
|
198
200
|
pass: config.esms.apiSecret,
|
|
199
201
|
to: formatPhoneNumber(phoneNumber),
|
|
200
202
|
msg: `RM0.00 FLUX verification code: ${code}`,
|
|
201
|
-
sender: 'FLUX'
|
|
203
|
+
sender: 'FLUX'
|
|
202
204
|
};
|
|
203
205
|
const result = await enhancedFetch('https://api.esms.com.my/sms/send', {
|
|
204
206
|
method: 'POST',
|
|
205
|
-
body: JSON.stringify(body)
|
|
207
|
+
body: JSON.stringify(body)
|
|
206
208
|
});
|
|
207
209
|
return result;
|
|
208
210
|
};
|
|
209
|
-
//# sourceMappingURL=verifications.js.map
|
package/dist/constants.js
CHANGED
package/dist/create-logger.js
CHANGED
|
@@ -3,16 +3,16 @@ import { Err } from '@driveflux/result';
|
|
|
3
3
|
import { getListByRef } from '../utils/lists.js';
|
|
4
4
|
import { callMailjet } from './request-service.js';
|
|
5
5
|
// Add a contact to a contact list in Mailjet
|
|
6
|
-
export const manageContactsInList = async ({ users, list, action = 'addnoforce'
|
|
7
|
-
const contacts = users.map((u)
|
|
6
|
+
export const manageContactsInList = async ({ users, list, action = 'addnoforce' })=>{
|
|
7
|
+
const contacts = users.map((u)=>{
|
|
8
8
|
return {
|
|
9
9
|
Email: u.email,
|
|
10
10
|
IsExcludedFromCampaigns: false,
|
|
11
11
|
Name: `${u.firstName} ${u.lastName}`,
|
|
12
12
|
Properties: {
|
|
13
13
|
FirstName: u.firstName,
|
|
14
|
-
LastName: u.lastName
|
|
15
|
-
}
|
|
14
|
+
LastName: u.lastName
|
|
15
|
+
}
|
|
16
16
|
};
|
|
17
17
|
});
|
|
18
18
|
const listOjbect = await getListByRef(list);
|
|
@@ -21,8 +21,7 @@ export const manageContactsInList = async ({ users, list, action = 'addnoforce',
|
|
|
21
21
|
}
|
|
22
22
|
const result = await callMailjet(`contactslist/${listOjbect.id}/managemanycontacts`, {
|
|
23
23
|
Action: action,
|
|
24
|
-
Contacts: contacts
|
|
24
|
+
Contacts: contacts
|
|
25
25
|
});
|
|
26
26
|
return result;
|
|
27
27
|
};
|
|
28
|
-
//# sourceMappingURL=manage-contacts-in-list.js.map
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { getLists } from '../utils/lists.js';
|
|
2
2
|
import { callMailjet } from './request-service.js';
|
|
3
|
-
export const manageSubscriptionStatus = async (email, updatedLists)
|
|
3
|
+
export const manageSubscriptionStatus = async (email, updatedLists)=>{
|
|
4
4
|
const lists = await getLists();
|
|
5
5
|
const data = {
|
|
6
|
-
ContactsLists: updatedLists.map((item)
|
|
6
|
+
ContactsLists: updatedLists.map((item)=>{
|
|
7
7
|
return {
|
|
8
8
|
Action: item.action,
|
|
9
|
-
ListID: lists[item.list]
|
|
9
|
+
ListID: lists[item.list]
|
|
10
10
|
};
|
|
11
|
-
})
|
|
11
|
+
})
|
|
12
12
|
};
|
|
13
13
|
const result = await callMailjet(`/contact/${email}/managecontactslists`, data);
|
|
14
14
|
return result;
|
|
15
15
|
};
|
|
16
|
-
//# sourceMappingURL=manage-subscription-status.js.map
|
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
import { config } from '@driveflux/email';
|
|
2
2
|
import { enhancedFetch } from '@driveflux/fetch';
|
|
3
|
-
const getAuth = ()
|
|
3
|
+
const getAuth = ()=>{
|
|
4
4
|
const authData = {
|
|
5
5
|
publicKey: config.mailjet.apiKeyPublic || process.env.MAILJET_API_KEY_PUBLIC,
|
|
6
|
-
privateKey: config.mailjet.apiKeyPrivate || process.env.MAILJET_API_KEY_PRIVATE
|
|
6
|
+
privateKey: config.mailjet.apiKeyPrivate || process.env.MAILJET_API_KEY_PRIVATE
|
|
7
7
|
};
|
|
8
8
|
const authLine = `${authData.publicKey}:${authData.privateKey}`;
|
|
9
9
|
return `Basic ${Buffer.from(authLine).toString('base64')}`;
|
|
10
10
|
};
|
|
11
11
|
const baseUrl = 'https://api.mailjet.com/v3/REST';
|
|
12
|
-
export const callMailjet = async (path, data, method = 'POST')
|
|
12
|
+
export const callMailjet = async (path, data, method = 'POST')=>{
|
|
13
13
|
const url = `${baseUrl}${path}`;
|
|
14
14
|
const result = await enhancedFetch(url, {
|
|
15
15
|
method,
|
|
16
16
|
headers: {
|
|
17
17
|
'Content-Type': 'application/json',
|
|
18
|
-
Authorization: getAuth()
|
|
18
|
+
Authorization: getAuth()
|
|
19
19
|
},
|
|
20
|
-
...
|
|
20
|
+
...method !== 'GET' ? {
|
|
21
|
+
body: JSON.stringify(data)
|
|
22
|
+
} : {}
|
|
21
23
|
});
|
|
22
24
|
return result;
|
|
23
25
|
};
|
|
24
|
-
//# sourceMappingURL=request-service.js.map
|
|
@@ -14,18 +14,18 @@ const userForRefreshEmailPreferencesQuery = {
|
|
|
14
14
|
subscriptions: {
|
|
15
15
|
select: {
|
|
16
16
|
ended: true,
|
|
17
|
-
active: true
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
17
|
+
active: true
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
21
|
};
|
|
22
|
-
export const refreshEmailPreferences = async (idOrUserForRefreshEmailPreferences)
|
|
23
|
-
const user = typeof idOrUserForRefreshEmailPreferences === 'string'
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
export const refreshEmailPreferences = async (idOrUserForRefreshEmailPreferences)=>{
|
|
23
|
+
const user = typeof idOrUserForRefreshEmailPreferences === 'string' ? await prisma.user.findUnique({
|
|
24
|
+
where: {
|
|
25
|
+
id: idOrUserForRefreshEmailPreferences
|
|
26
|
+
},
|
|
27
|
+
...userForRefreshEmailPreferencesQuery
|
|
28
|
+
}) : idOrUserForRefreshEmailPreferences;
|
|
29
29
|
if (!user) {
|
|
30
30
|
return new Err(makeProblem(PROBLEM_NOT_FOUND, 'User not found'));
|
|
31
31
|
}
|
|
@@ -40,4 +40,3 @@ export const refreshEmailPreferences = async (idOrUserForRefreshEmailPreferences
|
|
|
40
40
|
const items = convertToArray(preferences, !!updated?.businessId);
|
|
41
41
|
return await manageSubscriptionStatus(user.email, items);
|
|
42
42
|
};
|
|
43
|
-
//# sourceMappingURL=refresh-email-preferences.js.map
|
|
@@ -13,18 +13,18 @@ const userForSetInContactListlPreferencesQuery = {
|
|
|
13
13
|
subscriptions: {
|
|
14
14
|
select: {
|
|
15
15
|
ended: true,
|
|
16
|
-
active: true
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
16
|
+
active: true
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
20
|
};
|
|
21
|
-
export const setContactInList = async (idOrUserForSetInContactListlPreferences, preferences)
|
|
22
|
-
const user = typeof idOrUserForSetInContactListlPreferences === 'string'
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
export const setContactInList = async (idOrUserForSetInContactListlPreferences, preferences)=>{
|
|
22
|
+
const user = typeof idOrUserForSetInContactListlPreferences === 'string' ? await prisma.user.findUnique({
|
|
23
|
+
where: {
|
|
24
|
+
id: idOrUserForSetInContactListlPreferences
|
|
25
|
+
},
|
|
26
|
+
...userForSetInContactListlPreferencesQuery
|
|
27
|
+
}) : idOrUserForSetInContactListlPreferences;
|
|
28
28
|
if (!user) {
|
|
29
29
|
return new Err(makeProblem(PROBLEM_NOT_FOUND, 'User not found'));
|
|
30
30
|
}
|
|
@@ -36,4 +36,3 @@ export const setContactInList = async (idOrUserForSetInContactListlPreferences,
|
|
|
36
36
|
const results = await manageSubscriptionStatus(user.email, items);
|
|
37
37
|
return new Ok(results);
|
|
38
38
|
};
|
|
39
|
-
//# sourceMappingURL=set-contact.js.map
|
package/dist/mailjet/types.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export {};
|
|
2
|
-
//# sourceMappingURL=types.js.map
|
|
1
|
+
export { };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export const convertToArray = (preferences, isBusiness)
|
|
1
|
+
export const convertToArray = (preferences, isBusiness)=>{
|
|
2
2
|
if (!preferences) {
|
|
3
3
|
return [];
|
|
4
4
|
}
|
|
@@ -6,18 +6,20 @@ export const convertToArray = (preferences, isBusiness) => {
|
|
|
6
6
|
if (typeof isBusiness === 'boolean') {
|
|
7
7
|
preferencesArray.push([
|
|
8
8
|
'activeSubBusiness',
|
|
9
|
-
!!preferences?.activeSub && isBusiness
|
|
9
|
+
!!preferences?.activeSub && isBusiness
|
|
10
10
|
]);
|
|
11
11
|
preferencesArray.push([
|
|
12
12
|
'activeSubPersonal',
|
|
13
|
-
!!preferences?.activeSub && !isBusiness
|
|
13
|
+
!!preferences?.activeSub && !isBusiness
|
|
14
14
|
]);
|
|
15
15
|
}
|
|
16
|
-
const items = preferencesArray.map(([key, value])
|
|
16
|
+
const items = preferencesArray.map(([key, value])=>{
|
|
17
17
|
const list = key;
|
|
18
18
|
const action = value ? 'addnoforce' : 'unsub';
|
|
19
|
-
return {
|
|
19
|
+
return {
|
|
20
|
+
list,
|
|
21
|
+
action
|
|
22
|
+
};
|
|
20
23
|
});
|
|
21
24
|
return items;
|
|
22
25
|
};
|
|
23
|
-
//# sourceMappingURL=convert-to-array.js.map
|