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