@driveflux/api-functions 0.0.2

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.
Files changed (174) hide show
  1. package/dist/auth/confirm.d.ts +33 -0
  2. package/dist/auth/confirm.d.ts.map +1 -0
  3. package/dist/auth/confirm.js +88 -0
  4. package/dist/auth/confirm.js.map +1 -0
  5. package/dist/auth/emails.d.ts +4 -0
  6. package/dist/auth/emails.d.ts.map +1 -0
  7. package/dist/auth/emails.js +51 -0
  8. package/dist/auth/emails.js.map +1 -0
  9. package/dist/auth/formatter.d.ts +2 -0
  10. package/dist/auth/formatter.d.ts.map +1 -0
  11. package/dist/auth/formatter.js +249 -0
  12. package/dist/auth/formatter.js.map +1 -0
  13. package/dist/auth/otp.d.ts +44 -0
  14. package/dist/auth/otp.d.ts.map +1 -0
  15. package/dist/auth/otp.js +154 -0
  16. package/dist/auth/otp.js.map +1 -0
  17. package/dist/auth/register.d.ts +31 -0
  18. package/dist/auth/register.d.ts.map +1 -0
  19. package/dist/auth/register.js +128 -0
  20. package/dist/auth/register.js.map +1 -0
  21. package/dist/auth/tokens.d.ts +62 -0
  22. package/dist/auth/tokens.d.ts.map +1 -0
  23. package/dist/auth/tokens.js +129 -0
  24. package/dist/auth/tokens.js.map +1 -0
  25. package/dist/auth/verifications.d.ts +28 -0
  26. package/dist/auth/verifications.d.ts.map +1 -0
  27. package/dist/auth/verifications.js +174 -0
  28. package/dist/auth/verifications.js.map +1 -0
  29. package/dist/constants.d.ts +5 -0
  30. package/dist/constants.d.ts.map +1 -0
  31. package/dist/constants.js +5 -0
  32. package/dist/constants.js.map +1 -0
  33. package/dist/global.d.js +1 -0
  34. package/dist/mailjet/calls/manage-contacts-in-list.d.ts +21 -0
  35. package/dist/mailjet/calls/manage-contacts-in-list.d.ts.map +1 -0
  36. package/dist/mailjet/calls/manage-contacts-in-list.js +28 -0
  37. package/dist/mailjet/calls/manage-contacts-in-list.js.map +1 -0
  38. package/dist/mailjet/calls/manage-subscription-status.d.ts +15 -0
  39. package/dist/mailjet/calls/manage-subscription-status.d.ts.map +1 -0
  40. package/dist/mailjet/calls/manage-subscription-status.js +16 -0
  41. package/dist/mailjet/calls/manage-subscription-status.js.map +1 -0
  42. package/dist/mailjet/calls/request-service.d.ts +7 -0
  43. package/dist/mailjet/calls/request-service.d.ts.map +1 -0
  44. package/dist/mailjet/calls/request-service.js +24 -0
  45. package/dist/mailjet/calls/request-service.js.map +1 -0
  46. package/dist/mailjet/refresh-email-preferences.d.ts +23 -0
  47. package/dist/mailjet/refresh-email-preferences.d.ts.map +1 -0
  48. package/dist/mailjet/refresh-email-preferences.js +43 -0
  49. package/dist/mailjet/refresh-email-preferences.js.map +1 -0
  50. package/dist/mailjet/set-contact.d.ts +21 -0
  51. package/dist/mailjet/set-contact.d.ts.map +1 -0
  52. package/dist/mailjet/set-contact.js +39 -0
  53. package/dist/mailjet/set-contact.js.map +1 -0
  54. package/dist/mailjet/types.d.ts +31 -0
  55. package/dist/mailjet/types.d.ts.map +1 -0
  56. package/dist/mailjet/types.js +2 -0
  57. package/dist/mailjet/types.js.map +1 -0
  58. package/dist/mailjet/utils/convert-to-array.d.ts +6 -0
  59. package/dist/mailjet/utils/convert-to-array.d.ts.map +1 -0
  60. package/dist/mailjet/utils/convert-to-array.js +23 -0
  61. package/dist/mailjet/utils/convert-to-array.js.map +1 -0
  62. package/dist/mailjet/utils/extract-email-preferences.d.ts +17 -0
  63. package/dist/mailjet/utils/extract-email-preferences.d.ts.map +1 -0
  64. package/dist/mailjet/utils/extract-email-preferences.js +51 -0
  65. package/dist/mailjet/utils/extract-email-preferences.js.map +1 -0
  66. package/dist/mailjet/utils/lists.d.ts +13 -0
  67. package/dist/mailjet/utils/lists.d.ts.map +1 -0
  68. package/dist/mailjet/utils/lists.js +41 -0
  69. package/dist/mailjet/utils/lists.js.map +1 -0
  70. package/dist/mailjet/utils/update-email-references.d.ts +4 -0
  71. package/dist/mailjet/utils/update-email-references.d.ts.map +1 -0
  72. package/dist/mailjet/utils/update-email-references.js +31 -0
  73. package/dist/mailjet/utils/update-email-references.js.map +1 -0
  74. package/dist/notion/client.d.ts +12 -0
  75. package/dist/notion/client.d.ts.map +1 -0
  76. package/dist/notion/client.js +63 -0
  77. package/dist/notion/client.js.map +1 -0
  78. package/dist/notion/helpful.d.ts +7 -0
  79. package/dist/notion/helpful.d.ts.map +1 -0
  80. package/dist/notion/helpful.js +32 -0
  81. package/dist/notion/helpful.js.map +1 -0
  82. package/dist/notion/schemas/block.d.ts +89 -0
  83. package/dist/notion/schemas/block.d.ts.map +1 -0
  84. package/dist/notion/schemas/block.js +89 -0
  85. package/dist/notion/schemas/block.js.map +1 -0
  86. package/dist/notion/schemas/common.d.ts +25 -0
  87. package/dist/notion/schemas/common.d.ts.map +1 -0
  88. package/dist/notion/schemas/common.js +31 -0
  89. package/dist/notion/schemas/common.js.map +1 -0
  90. package/dist/notion/schemas/database.d.ts +517 -0
  91. package/dist/notion/schemas/database.d.ts.map +1 -0
  92. package/dist/notion/schemas/database.js +222 -0
  93. package/dist/notion/schemas/database.js.map +1 -0
  94. package/dist/notion/schemas/emoji.d.ts +12 -0
  95. package/dist/notion/schemas/emoji.d.ts.map +1 -0
  96. package/dist/notion/schemas/emoji.js +6 -0
  97. package/dist/notion/schemas/emoji.js.map +1 -0
  98. package/dist/notion/schemas/file.d.ts +43 -0
  99. package/dist/notion/schemas/file.d.ts.map +1 -0
  100. package/dist/notion/schemas/file.js +18 -0
  101. package/dist/notion/schemas/file.js.map +1 -0
  102. package/dist/notion/schemas/kb.d.ts +1526 -0
  103. package/dist/notion/schemas/kb.d.ts.map +1 -0
  104. package/dist/notion/schemas/kb.js +74 -0
  105. package/dist/notion/schemas/kb.js.map +1 -0
  106. package/dist/notion/schemas/page.d.ts +608 -0
  107. package/dist/notion/schemas/page.d.ts.map +1 -0
  108. package/dist/notion/schemas/page.js +181 -0
  109. package/dist/notion/schemas/page.js.map +1 -0
  110. package/dist/notion/schemas/parent.d.ts +42 -0
  111. package/dist/notion/schemas/parent.d.ts.map +1 -0
  112. package/dist/notion/schemas/parent.js +18 -0
  113. package/dist/notion/schemas/parent.js.map +1 -0
  114. package/dist/notion/schemas/user.d.ts +83 -0
  115. package/dist/notion/schemas/user.d.ts.map +1 -0
  116. package/dist/notion/schemas/user.js +31 -0
  117. package/dist/notion/schemas/user.js.map +1 -0
  118. package/dist/reservation/agree.d.ts +3 -0
  119. package/dist/reservation/agree.d.ts.map +1 -0
  120. package/dist/reservation/agree.js +23 -0
  121. package/dist/reservation/agree.js.map +1 -0
  122. package/dist/reservation/checks.d.ts +8 -0
  123. package/dist/reservation/checks.d.ts.map +1 -0
  124. package/dist/reservation/checks.js +28 -0
  125. package/dist/reservation/checks.js.map +1 -0
  126. package/dist/reservation/display-vehicle.d.ts +1152 -0
  127. package/dist/reservation/display-vehicle.d.ts.map +1 -0
  128. package/dist/reservation/display-vehicle.js +244 -0
  129. package/dist/reservation/display-vehicle.js.map +1 -0
  130. package/dist/reservation/fetch-or-create.d.ts +11 -0
  131. package/dist/reservation/fetch-or-create.d.ts.map +1 -0
  132. package/dist/reservation/fetch-or-create.js +207 -0
  133. package/dist/reservation/fetch-or-create.js.map +1 -0
  134. package/dist/reservation/invoice.d.ts +12 -0
  135. package/dist/reservation/invoice.d.ts.map +1 -0
  136. package/dist/reservation/invoice.js +248 -0
  137. package/dist/reservation/invoice.js.map +1 -0
  138. package/dist/reservation/payer.d.ts +5 -0
  139. package/dist/reservation/payer.d.ts.map +1 -0
  140. package/dist/reservation/payer.js +38 -0
  141. package/dist/reservation/payer.js.map +1 -0
  142. package/dist/reservation/reserve.d.ts +5 -0
  143. package/dist/reservation/reserve.d.ts.map +1 -0
  144. package/dist/reservation/reserve.js +44 -0
  145. package/dist/reservation/reserve.js.map +1 -0
  146. package/dist/reservation/types.d.ts +28 -0
  147. package/dist/reservation/types.d.ts.map +1 -0
  148. package/dist/reservation/types.js +2 -0
  149. package/dist/reservation/types.js.map +1 -0
  150. package/dist/reservation/vehicle.d.ts +6 -0
  151. package/dist/reservation/vehicle.d.ts.map +1 -0
  152. package/dist/reservation/vehicle.js +32 -0
  153. package/dist/reservation/vehicle.js.map +1 -0
  154. package/dist/slack.d.ts +19 -0
  155. package/dist/slack.d.ts.map +1 -0
  156. package/dist/slack.js +105 -0
  157. package/dist/slack.js.map +1 -0
  158. package/dist/validation.d.ts +63 -0
  159. package/dist/validation.d.ts.map +1 -0
  160. package/dist/validation.js +99 -0
  161. package/dist/validation.js.map +1 -0
  162. package/dist/vehicle/vehicle-pricing/constants.d.ts +91 -0
  163. package/dist/vehicle/vehicle-pricing/constants.d.ts.map +1 -0
  164. package/dist/vehicle/vehicle-pricing/constants.js +142 -0
  165. package/dist/vehicle/vehicle-pricing/constants.js.map +1 -0
  166. package/dist/vehicle/vehicle-pricing/index.d.ts +79 -0
  167. package/dist/vehicle/vehicle-pricing/index.d.ts.map +1 -0
  168. package/dist/vehicle/vehicle-pricing/index.js +169 -0
  169. package/dist/vehicle/vehicle-pricing/index.js.map +1 -0
  170. package/dist/vehicle/vehicle-pricing/types.d.ts +43 -0
  171. package/dist/vehicle/vehicle-pricing/types.d.ts.map +1 -0
  172. package/dist/vehicle/vehicle-pricing/types.js +2 -0
  173. package/dist/vehicle/vehicle-pricing/types.js.map +1 -0
  174. package/package.json +121 -0
@@ -0,0 +1,33 @@
1
+ import { type Token, type User } from '@driveflux/db';
2
+ import { type PromisedResult } from '@driveflux/result';
3
+ import { z } from 'zod';
4
+ type ConfirmUserApiResponse = {
5
+ token: Token;
6
+ user: User;
7
+ };
8
+ export type ConfirmUserOptions = z.infer<typeof Body>;
9
+ declare const Body: z.ZodObject<{
10
+ firstName: z.ZodString;
11
+ lastName: z.ZodString;
12
+ phoneNumber: z.ZodEffects<z.ZodString, string, string>;
13
+ code: z.ZodNullable<z.ZodOptional<z.ZodString>>;
14
+ email: z.ZodEffects<z.ZodString, string, string>;
15
+ pageSource: z.ZodNullable<z.ZodOptional<z.ZodString>>;
16
+ }, "strip", z.ZodTypeAny, {
17
+ firstName: string;
18
+ lastName: string;
19
+ email: string;
20
+ phoneNumber: string;
21
+ code?: string | null | undefined;
22
+ pageSource?: string | null | undefined;
23
+ }, {
24
+ firstName: string;
25
+ lastName: string;
26
+ email: string;
27
+ phoneNumber: string;
28
+ code?: string | null | undefined;
29
+ pageSource?: string | null | undefined;
30
+ }>;
31
+ export declare const handleConfirmUser: (b: Record<string, unknown>, user: Pick<User, "id" | "phoneNumberVerified" | "metadata">, xForwardedFor?: string | string[]) => PromisedResult<ConfirmUserApiResponse>;
32
+ export {};
33
+ //# sourceMappingURL=confirm.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm.d.ts","sourceRoot":"","sources":["../../src/auth/confirm.ts"],"names":[],"mappings":"AACA,OAAO,EAAU,KAAK,KAAK,EAAE,KAAK,IAAI,EAAE,MAAM,eAAe,CAAA;AAG7D,OAAO,EAAW,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAGhE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,KAAK,sBAAsB,GAAG;IAC7B,KAAK,EAAE,KAAK,CAAA;IACZ,IAAI,EAAE,IAAI,CAAA;CACV,CAAA;AAED,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAA;AAErD,QAAA,MAAM,IAAI;;;;;;;iBAUR,CAAA;AAEF,eAAO,MAAM,iBAAiB,GAC7B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1B,MAAM,IAAI,CAAC,IAAI,EAAE,IAAI,GAAG,qBAAqB,GAAG,UAAU,CAAC,EAC3D,gBAAgB,MAAM,GAAG,MAAM,EAAE,KAC/B,cAAc,CAAC,sBAAsB,CAyEvC,CAAA"}
@@ -0,0 +1,88 @@
1
+ import { refreshEmailPreferences } from '@driveflux/api-functions/mailjet/refresh-email-preferences';
2
+ import { prisma } from '@driveflux/db';
3
+ import { generateId } from '@driveflux/db/id';
4
+ import { makeProblem, PROBLEM_CONFLICT } from '@driveflux/problem';
5
+ import { Err, Ok } from '@driveflux/result';
6
+ import { isMetadata } from '@driveflux/utils';
7
+ import { addDays } from 'date-fns/addDays';
8
+ import { z } from 'zod';
9
+ import { clearToken, verifyToken } from './tokens.js';
10
+ import { sendVerificationEmail } from './verifications.js';
11
+ const Body = z.object({
12
+ firstName: z.string(),
13
+ lastName: z.string(),
14
+ phoneNumber: z.string().transform((s) => s.replace(/[\s-]/g, '')),
15
+ code: z.string().optional().nullable(),
16
+ email: z
17
+ .string()
18
+ .email()
19
+ .transform((s) => s.toLowerCase().trim()),
20
+ pageSource: z.string().optional().nullable(),
21
+ });
22
+ export const handleConfirmUser = async (b, user, xForwardedFor) => {
23
+ const { phoneNumber, email, code, pageSource, ...body } = Body.parse(b);
24
+ let phoneNumberVerified = false;
25
+ if (code) {
26
+ const tokenResult = await verifyToken(code, { scope: 'verify-phone' });
27
+ if (tokenResult.err) {
28
+ return new Err(makeProblem(PROBLEM_CONFLICT, 'Invalid OTP token'));
29
+ }
30
+ await clearToken(tokenResult.val.id);
31
+ phoneNumberVerified = true;
32
+ }
33
+ else {
34
+ phoneNumberVerified = user.phoneNumberVerified;
35
+ }
36
+ const method = isMetadata(user?.metadata)
37
+ ? user?.metadata?.signupProvider
38
+ : undefined;
39
+ const updatedUser = await prisma.user.update({
40
+ where: {
41
+ id: user.id,
42
+ },
43
+ data: {
44
+ ...body,
45
+ phoneNumber: phoneNumber?.replace(/[\s-]/g, ''),
46
+ preferredCurrency: 'MYR',
47
+ preferredLocale: 'en',
48
+ phoneNumberVerified,
49
+ consented: true,
50
+ groups: ['member'],
51
+ signupParams: {
52
+ method,
53
+ source: pageSource,
54
+ },
55
+ consents: {
56
+ create: {
57
+ id: generateId('UserConsent'),
58
+ ipAddress: Array.isArray(xForwardedFor)
59
+ ? xForwardedFor?.[0] || '0.0.0.0'
60
+ : xForwardedFor || '0.0.0.0',
61
+ consentType: 'terms',
62
+ email: email,
63
+ },
64
+ },
65
+ registrationComplete: true,
66
+ },
67
+ });
68
+ const token = await prisma.token.create({
69
+ data: {
70
+ id: generateId('Token'),
71
+ user: {
72
+ connect: {
73
+ id: updatedUser.id,
74
+ },
75
+ },
76
+ expiresAt: addDays(new Date(), 365),
77
+ scope: 'all',
78
+ },
79
+ });
80
+ // We don't want this to be a task. It should be instant
81
+ await sendVerificationEmail(updatedUser.id);
82
+ await refreshEmailPreferences(updatedUser.id);
83
+ return new Ok({
84
+ token,
85
+ user: updatedUser,
86
+ });
87
+ };
88
+ //# sourceMappingURL=confirm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"confirm.js","sourceRoot":"","sources":["../../src/auth/confirm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { send } from '@driveflux/email';
2
+ export declare const sendEmailChangedEmail: (userId: string) => ReturnType<typeof send>;
3
+ export declare const sendPasswordChangedEmail: (userId: string) => ReturnType<typeof send>;
4
+ //# sourceMappingURL=emails.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emails.d.ts","sourceRoot":"","sources":["../../src/auth/emails.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AAMvC,eAAO,MAAM,qBAAqB,GACjC,QAAQ,MAAM,KACZ,UAAU,CAAC,OAAO,IAAI,CAyBxB,CAAA;AAED,eAAO,MAAM,wBAAwB,GACpC,QAAQ,MAAM,KACZ,UAAU,CAAC,OAAO,IAAI,CA0BxB,CAAA"}
@@ -0,0 +1,51 @@
1
+ import { prisma } from '@driveflux/db';
2
+ import { send } from '@driveflux/email';
3
+ import { emailChangedEmail } from '@driveflux/email-templates/flux/email-changed';
4
+ import { passwordChangedEmail } from '@driveflux/email-templates/flux/password-changed';
5
+ import { makeProblem, PROBLEM_NOT_FOUND } from '@driveflux/problem';
6
+ import { Err } from '@driveflux/result';
7
+ export const sendEmailChangedEmail = async (userId) => {
8
+ const user = await prisma.user.findUnique({
9
+ where: {
10
+ id: userId,
11
+ },
12
+ });
13
+ if (!user) {
14
+ return new Err(makeProblem(PROBLEM_NOT_FOUND, `The user ${userId} was not found`));
15
+ }
16
+ return await send({
17
+ subject: 'Email change confirmation',
18
+ to: {
19
+ name: user.firstName || '',
20
+ address: user.email,
21
+ },
22
+ html: emailChangedEmail({
23
+ user: user.firstName || '',
24
+ title: 'Email change confirmation',
25
+ newEmail: user.email,
26
+ }),
27
+ });
28
+ };
29
+ export const sendPasswordChangedEmail = async (userId) => {
30
+ const user = await prisma.user.findUnique({
31
+ where: {
32
+ id: userId,
33
+ },
34
+ });
35
+ if (!user) {
36
+ return new Err(makeProblem(PROBLEM_NOT_FOUND, `The user ${userId} was not found`));
37
+ }
38
+ const title = 'Password changed';
39
+ return await send({
40
+ subject: title,
41
+ to: {
42
+ name: user.firstName || '',
43
+ address: user.email,
44
+ },
45
+ html: passwordChangedEmail({
46
+ user: user.firstName || '',
47
+ title: title,
48
+ }),
49
+ });
50
+ };
51
+ //# sourceMappingURL=emails.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emails.js","sourceRoot":"","sources":["../../src/auth/emails.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,+CAA+C,CAAA;AACjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,kDAAkD,CAAA;AACvF,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACnE,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAA;AAEvC,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,EACzC,MAAc,EACY,EAAE;IAC5B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;QACzC,KAAK,EAAE;YACN,EAAE,EAAE,MAAM;SACV;KACD,CAAC,CAAA;IAEF,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,OAAO,IAAI,GAAG,CACb,WAAW,CAAC,iBAAiB,EAAE,YAAY,MAAM,gBAAgB,CAAC,CAClE,CAAA;IACF,CAAC;IAED,OAAO,MAAM,IAAI,CAAC;QACjB,OAAO,EAAE,2BAA2B;QACpC,EAAE,EAAE;YACH,IAAI,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE;YAC1B,OAAO,EAAE,IAAI,CAAC,KAAK;SACnB;QACD,IAAI,EAAE,iBAAiB,CAAC;YACvB,IAAI,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE;YAC1B,KAAK,EAAE,2BAA2B;YAClC,QAAQ,EAAE,IAAI,CAAC,KAAK;SACpB,CAAC;KACF,CAAC,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,wBAAwB,GAAG,KAAK,EAC5C,MAAc,EACY,EAAE;IAC5B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;QACzC,KAAK,EAAE;YACN,EAAE,EAAE,MAAM;SACV;KACD,CAAC,CAAA;IAEF,IAAI,CAAC,IAAI,EAAE,CAAC;QACX,OAAO,IAAI,GAAG,CACb,WAAW,CAAC,iBAAiB,EAAE,YAAY,MAAM,gBAAgB,CAAC,CAClE,CAAA;IACF,CAAC;IAED,MAAM,KAAK,GAAG,kBAAkB,CAAA;IAEhC,OAAO,MAAM,IAAI,CAAC;QACjB,OAAO,EAAE,KAAK;QACd,EAAE,EAAE;YACH,IAAI,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE;YAC1B,OAAO,EAAE,IAAI,CAAC,KAAK;SACnB;QACD,IAAI,EAAE,oBAAoB,CAAC;YAC1B,IAAI,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE;YAC1B,KAAK,EAAE,KAAK;SACZ,CAAC;KACF,CAAC,CAAA;AACH,CAAC,CAAA"}
@@ -0,0 +1,2 @@
1
+ export declare const cleanupPhoneNumber: (phoneNumber: string) => string;
2
+ //# sourceMappingURL=formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../src/auth/formatter.ts"],"names":[],"mappings":"AAkOA,eAAO,MAAM,kBAAkB,GAAI,aAAa,MAAM,KAAG,MA2BxD,CAAA"}
@@ -0,0 +1,249 @@
1
+ const knownCountryCodes = [
2
+ '1',
3
+ '376',
4
+ '93',
5
+ '1268',
6
+ '1264',
7
+ '355',
8
+ '374',
9
+ '244',
10
+ '672',
11
+ '54',
12
+ '1684',
13
+ '43',
14
+ '61',
15
+ '297',
16
+ '358',
17
+ '994',
18
+ '387',
19
+ '1246',
20
+ '880',
21
+ '32',
22
+ '226',
23
+ '359',
24
+ '973',
25
+ '257',
26
+ '229',
27
+ '590',
28
+ '1441',
29
+ '673',
30
+ '591',
31
+ '5997',
32
+ '55',
33
+ '975',
34
+ '47',
35
+ '267',
36
+ '375',
37
+ '501',
38
+ '41',
39
+ '225',
40
+ '56',
41
+ '237',
42
+ '86',
43
+ '57',
44
+ '506',
45
+ '53',
46
+ '238',
47
+ '599',
48
+ '357',
49
+ '49',
50
+ '253',
51
+ '45',
52
+ '767',
53
+ '213',
54
+ '593',
55
+ '372',
56
+ '20',
57
+ '212',
58
+ '291',
59
+ '34',
60
+ '251',
61
+ '679',
62
+ '691',
63
+ '33',
64
+ '241',
65
+ '1473',
66
+ '995',
67
+ '594',
68
+ '44',
69
+ '233',
70
+ '350',
71
+ '299',
72
+ '224',
73
+ '240',
74
+ '30',
75
+ '500',
76
+ '502',
77
+ '245',
78
+ '592',
79
+ '852',
80
+ '504',
81
+ '385',
82
+ '509',
83
+ '36',
84
+ '62',
85
+ '353',
86
+ '972',
87
+ '91',
88
+ '964',
89
+ '98',
90
+ '354',
91
+ '39',
92
+ '876',
93
+ '962',
94
+ '81',
95
+ '254',
96
+ '996',
97
+ '855',
98
+ '850',
99
+ '82',
100
+ '686',
101
+ '1869',
102
+ '965',
103
+ '7',
104
+ '961',
105
+ '1758',
106
+ '423',
107
+ '94',
108
+ '231',
109
+ '266',
110
+ '370',
111
+ '352',
112
+ '371',
113
+ '218',
114
+ '377',
115
+ '382',
116
+ '261',
117
+ '223',
118
+ '95',
119
+ '976',
120
+ '853',
121
+ '596',
122
+ '222',
123
+ '1664',
124
+ '356',
125
+ '230',
126
+ '960',
127
+ '265',
128
+ '52',
129
+ '60',
130
+ '258',
131
+ '264',
132
+ '687',
133
+ '234',
134
+ '505',
135
+ '977',
136
+ '674',
137
+ '683',
138
+ '64',
139
+ '968',
140
+ '507',
141
+ '51',
142
+ '689',
143
+ '675',
144
+ '92',
145
+ '48',
146
+ '508',
147
+ '970',
148
+ '351',
149
+ '680',
150
+ '595',
151
+ '974',
152
+ '262',
153
+ '40',
154
+ '381',
155
+ '250',
156
+ '966',
157
+ '677',
158
+ '248',
159
+ '46',
160
+ '65',
161
+ '290',
162
+ '386',
163
+ '4779',
164
+ '421',
165
+ '232',
166
+ '378',
167
+ '221',
168
+ '252',
169
+ '597',
170
+ '211',
171
+ '239',
172
+ '503',
173
+ '1721',
174
+ '963',
175
+ '235',
176
+ '228',
177
+ '66',
178
+ '992',
179
+ '690',
180
+ '670',
181
+ '993',
182
+ '216',
183
+ '676',
184
+ '90',
185
+ '868',
186
+ '688',
187
+ '255',
188
+ '380',
189
+ '256',
190
+ '598',
191
+ '998',
192
+ '1784',
193
+ '58',
194
+ '1284',
195
+ '1340',
196
+ '84',
197
+ '678',
198
+ '681',
199
+ '685',
200
+ '967',
201
+ '27',
202
+ '260',
203
+ '263',
204
+ '268',
205
+ '389',
206
+ '63',
207
+ '31',
208
+ '971',
209
+ '373',
210
+ '220',
211
+ '249',
212
+ '856',
213
+ '886',
214
+ '242',
215
+ '420',
216
+ '227',
217
+ '243',
218
+ '236',
219
+ '682',
220
+ '298',
221
+ '246',
222
+ '269',
223
+ '692',
224
+ '383',
225
+ ];
226
+ export const cleanupPhoneNumber = (phoneNumber) => {
227
+ // Remove all characters except numbers and +
228
+ const cleaned = phoneNumber.replace(/[^\d+]/g, '');
229
+ // If it doesn't start with +, add it
230
+ const withPlus = cleaned.startsWith('+') ? cleaned : `+${cleaned}`;
231
+ // Find the country code by checking against known codes
232
+ let countryCode = '';
233
+ let remainingNumber = '';
234
+ // Try to find the country code by checking the longest matches first
235
+ for (let i = 4; i >= 1; i--) {
236
+ const potentialCode = withPlus.substring(1, 1 + i); // Skip the + and take i digits
237
+ if (knownCountryCodes.includes(potentialCode)) {
238
+ countryCode = potentialCode;
239
+ remainingNumber = withPlus.substring(1 + i); // Everything after the country code
240
+ break;
241
+ }
242
+ }
243
+ // If we found a country code and the remaining number starts with 0, remove it
244
+ if (countryCode && remainingNumber.startsWith('0')) {
245
+ return `+${countryCode}${remainingNumber.substring(1)}`;
246
+ }
247
+ return withPlus;
248
+ };
249
+ //# sourceMappingURL=formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../../src/auth/formatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { type User } from '@driveflux/db';
2
+ import { Err, Ok, type PromisedResult } from '@driveflux/result';
3
+ import { z } from 'zod';
4
+ export type VerifyOTPOnlyApiResponse = {
5
+ phoneNumber: string;
6
+ phoneNumberVerified: boolean;
7
+ };
8
+ export type VerifyOTPOnlyOptions = z.infer<typeof VerifyOtpOnlyBody>;
9
+ export type VerifyOTPApiResponse = {
10
+ accessToken: string;
11
+ expiresAt: string | Date | null;
12
+ user: User;
13
+ };
14
+ export type VerifyOTPOptions = z.input<typeof VerifyOtpBody>;
15
+ export type SendVerificationSMSOptions = z.infer<typeof SendVerificationSMSBody>;
16
+ declare const SendVerificationSMSBody: z.ZodObject<{
17
+ phoneNumber: z.ZodString;
18
+ checkDuplication: z.ZodNullable<z.ZodOptional<z.ZodBoolean>>;
19
+ includeUser: z.ZodNullable<z.ZodOptional<z.ZodBoolean>>;
20
+ userId: z.ZodNullable<z.ZodOptional<z.ZodString>>;
21
+ }, z.core.$strip>;
22
+ declare const VerifyOtpBody: z.ZodObject<{
23
+ scope: z.ZodEnum<{
24
+ "verify-email": "verify-email";
25
+ "verify-phone": "verify-phone";
26
+ }>;
27
+ email: z.ZodPipe<z.ZodOptional<z.ZodEmail>, z.ZodTransform<string | undefined, string | undefined>>;
28
+ phoneNumber: z.ZodOptional<z.ZodString>;
29
+ code: z.ZodString;
30
+ }, z.core.$strip>;
31
+ declare const VerifyOtpOnlyBody: z.ZodObject<{
32
+ phoneNumber: z.ZodOptional<z.ZodString>;
33
+ code: z.ZodString;
34
+ }, z.core.$strip>;
35
+ export declare const handleVerifyOTPOnly: ({ phoneNumber, code, }: VerifyOTPOnlyOptions) => Promise<Err<import("@driveflux/problem").Problem, unknown> | Ok<{
36
+ phoneNumber: string | undefined;
37
+ phoneNumberVerified: boolean;
38
+ }, unknown>>;
39
+ export declare const handleVerifyOTP: (b: Record<string, unknown>) => PromisedResult<VerifyOTPApiResponse>;
40
+ export declare const handleSendVerificationSMS: (b: Record<string, unknown>) => Promise<Err<import("@driveflux/problem").Problem, unknown> | Ok<{
41
+ success: boolean;
42
+ }, unknown>>;
43
+ export {};
44
+ //# sourceMappingURL=otp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otp.d.ts","sourceRoot":"","sources":["../../src/auth/otp.ts"],"names":[],"mappings":"AAEA,OAAO,EAAuB,KAAK,IAAI,EAAE,MAAM,eAAe,CAAA;AAO9D,OAAO,EAAE,GAAG,EAAE,EAAE,EAAE,KAAK,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAEhE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAKvB,MAAM,MAAM,wBAAwB,GAAG;IACtC,WAAW,EAAE,MAAM,CAAA;IACnB,mBAAmB,EAAE,OAAO,CAAA;CAC5B,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAA;AAEpE,MAAM,MAAM,oBAAoB,GAAG;IAClC,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,CAAA;IAC/B,IAAI,EAAE,IAAI,CAAA;CACV,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAA;AAE5D,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAA;AAEhF,QAAA,MAAM,uBAAuB;;;;;iBAK3B,CAAA;AAEF,QAAA,MAAM,aAAa;;;;;;;;iBAmCjB,CAAA;AAOF,QAAA,MAAM,iBAAiB;;;iBAGrB,CAAA;AAEF,eAAO,MAAM,mBAAmB,GAAU,wBAGvC,oBAAoB;;;YAgBtB,CAAA;AAED,eAAO,MAAM,eAAe,GAC3B,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACxB,cAAc,CAAC,oBAAoB,CA2ErC,CAAA;AAED,eAAO,MAAM,yBAAyB,GAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;;YAiDzE,CAAA"}
@@ -0,0 +1,154 @@
1
+ import { ROLES } from '@driveflux/auth/authorization/constants';
2
+ import { config } from '@driveflux/config/backend';
3
+ import { prisma } from '@driveflux/db';
4
+ import { generateId } from '@driveflux/db/id';
5
+ import { makeProblem, PROBLEM_CONFLICT, PROBLEM_INVALID_DATA, } from '@driveflux/problem';
6
+ import { Err, Ok } from '@driveflux/result';
7
+ import { addDays } from 'date-fns/addDays';
8
+ import { z } from 'zod';
9
+ import { sendEmailChangedEmail } from './emails.js';
10
+ import { clearToken, createSMSToken, verifyToken } from './tokens.js';
11
+ import { sendVerificationSMS } from './verifications.js';
12
+ const SendVerificationSMSBody = z.object({
13
+ phoneNumber: z.string(),
14
+ checkDuplication: z.boolean().optional().nullable(),
15
+ includeUser: z.boolean().optional().nullable(),
16
+ userId: z.string().optional().nullable(),
17
+ });
18
+ const VerifyOtpBody = z
19
+ .object({
20
+ scope: z.enum(['verify-email', 'verify-phone']),
21
+ email: z
22
+ .email()
23
+ .optional()
24
+ .transform((email) => email?.toLowerCase().trim()),
25
+ phoneNumber: z.string().optional(),
26
+ code: z.string(),
27
+ })
28
+ .refine((d) => {
29
+ if (d.scope === 'verify-email' && !d.email) {
30
+ return false;
31
+ }
32
+ return true;
33
+ }, {
34
+ path: ['email'],
35
+ message: 'Email is required',
36
+ })
37
+ .refine((d) => {
38
+ if (d.scope === 'verify-phone' && !d.phoneNumber) {
39
+ return false;
40
+ }
41
+ return true;
42
+ }, {
43
+ path: ['phoneNumber'],
44
+ message: 'Phone number is required',
45
+ });
46
+ const INVALID_TOKEN_PROBLEM = makeProblem(PROBLEM_INVALID_DATA, 'Unable to verify token. It could have been expired.');
47
+ const VerifyOtpOnlyBody = z.object({
48
+ phoneNumber: z.string().optional(),
49
+ code: z.string(),
50
+ });
51
+ export const handleVerifyOTPOnly = async ({ phoneNumber, code, }) => {
52
+ const tokenResult = await verifyToken(code, { scope: 'verify-phone' });
53
+ if (tokenResult.err) {
54
+ console.log('Error verifying token', tokenResult.val);
55
+ return new Err(INVALID_TOKEN_PROBLEM);
56
+ }
57
+ // delete the previous token
58
+ // TODO maybe: verify this token when registering one more time then clear it
59
+ // await clearToken(tokenResult.val.id)
60
+ return new Ok({
61
+ phoneNumber,
62
+ phoneNumberVerified: true,
63
+ });
64
+ };
65
+ export const handleVerifyOTP = async (b) => {
66
+ const { scope, email, phoneNumber: preFormattedPhoneNumber, code, } = VerifyOtpBody.parse(b);
67
+ const phoneNumber = `+${preFormattedPhoneNumber?.replace(/[^0-9]/g, '')}`;
68
+ const tokenResult = await verifyToken(code, { scope, metadata: { email, phoneNumber } }, { includeUser: true });
69
+ if (tokenResult.err) {
70
+ return new Err(INVALID_TOKEN_PROBLEM);
71
+ }
72
+ if (!tokenResult.val.user) {
73
+ return new Err(INVALID_TOKEN_PROBLEM);
74
+ }
75
+ const previousUser = tokenResult.val.user;
76
+ const userUpdate = scope === 'verify-email'
77
+ ? {
78
+ emailVerified: true,
79
+ email,
80
+ }
81
+ : {
82
+ phoneNumberVerified: true,
83
+ phoneNumber,
84
+ };
85
+ userUpdate.temporary = false;
86
+ userUpdate.temporaryEmail = null;
87
+ const userGroups = new Set(tokenResult.val.user?.groups);
88
+ userGroups.add(ROLES.MEMBER);
89
+ userUpdate.groups = [...userGroups];
90
+ const user = await prisma.user.update({
91
+ where: {
92
+ id: tokenResult.val.user.id,
93
+ },
94
+ data: userUpdate,
95
+ });
96
+ // delete the previous token
97
+ await clearToken(tokenResult.val.id);
98
+ // Login the user
99
+ const token = await prisma.token.create({
100
+ data: {
101
+ id: generateId('Token'),
102
+ user: {
103
+ connect: {
104
+ id: user?.id,
105
+ },
106
+ },
107
+ expiresAt: addDays(new Date(), 365),
108
+ scope: 'all',
109
+ },
110
+ });
111
+ if (previousUser.email !== user.email) {
112
+ await sendEmailChangedEmail(user.id);
113
+ }
114
+ return new Ok({
115
+ accessToken: token.id,
116
+ expiresAt: token.expiresAt,
117
+ user: user,
118
+ });
119
+ };
120
+ export const handleSendVerificationSMS = async (b) => {
121
+ const { phoneNumber, checkDuplication, userId } = SendVerificationSMSBody.parse(b);
122
+ const formattedPhoneNumber = `+${phoneNumber.replace(/[^0-9]/g, '')}`;
123
+ if (checkDuplication) {
124
+ const user = await prisma.user.findFirst({
125
+ where: {
126
+ OR: [
127
+ { phoneNumber: formattedPhoneNumber },
128
+ { phoneNumber: phoneNumber },
129
+ ],
130
+ phoneNumberVerified: true,
131
+ },
132
+ });
133
+ if (user) {
134
+ return new Err(makeProblem(PROBLEM_CONFLICT, 'This phone number is already registered'));
135
+ }
136
+ }
137
+ if (!config.isProd && !config.sendSMSOutsideOfProd) {
138
+ const code = await createSMSToken(userId || null, formattedPhoneNumber);
139
+ if (!code?.value) {
140
+ return new Err(makeProblem(PROBLEM_INVALID_DATA, 'Invalid Data'));
141
+ }
142
+ return new Ok({
143
+ success: true,
144
+ code: code.value,
145
+ });
146
+ }
147
+ // Send the sms verification
148
+ const verificationResult = await sendVerificationSMS(userId || null, phoneNumber);
149
+ if (verificationResult.err) {
150
+ return verificationResult;
151
+ }
152
+ return new Ok({ success: true });
153
+ };
154
+ //# sourceMappingURL=otp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"otp.js","sourceRoot":"","sources":["../../src/auth/otp.ts"],"names":[],"mappings":"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"}