customer-registration 0.0.104 → 0.0.106

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 (25) hide show
  1. package/.medusa/server/src/api/auth/customer/emailpass/reset-password/route.js +193 -0
  2. package/.medusa/server/src/api/auth/customer/emailpass/update/route.js +61 -0
  3. package/.medusa/server/src/api/store/customers/change-password/route.js +52 -0
  4. package/.medusa/server/src/api/store/customers/otp/verify/route.js +1 -14
  5. package/.medusa/server/src/helpers/base-client.js +36 -0
  6. package/.medusa/server/src/helpers/index.js +16 -0
  7. package/.medusa/server/src/helpers/reset-password.js +205 -0
  8. package/.medusa/server/src/modules/otp-verification/migrations/Migration20250120000000RemoveForgotPasswordFromOtpPurpose.js +33 -0
  9. package/.medusa/server/src/modules/otp-verification/models/otp-verification.js +2 -3
  10. package/.medusa/server/src/modules/otp-verification/service.js +102 -1
  11. package/.medusa/server/src/modules/password-management/index.js +12 -0
  12. package/.medusa/server/src/modules/password-management/service.js +200 -0
  13. package/.medusa/server/src/subscribers/customer-updated.js +100 -0
  14. package/.medusa/server/src/subscribers/password-reset.js +184 -0
  15. package/.medusa/server/src/utils/email-validation.js +20 -0
  16. package/.medusa/server/src/utils/password-hashing.js +93 -0
  17. package/.medusa/server/src/utils/password-validation.js +45 -0
  18. package/.medusa/server/src/workflows/change-password.js +117 -0
  19. package/.medusa/server/src/workflows/steps/find-customer-by-email-step.js +23 -0
  20. package/.medusa/server/src/workflows/steps/index.js +6 -2
  21. package/.medusa/server/src/workflows/steps/send-notification-step.js +91 -5
  22. package/.medusa/server/src/workflows/steps/update-password-step.js +44 -0
  23. package/README.md +62 -17
  24. package/package.json +6 -2
  25. package/.medusa/server/src/workflows/generate-password-reset-token.js +0 -38
@@ -0,0 +1,193 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.POST = void 0;
4
+ const utils_1 = require("@medusajs/framework/utils");
5
+ const generate_jwt_token_1 = require("@medusajs/medusa/api/auth/utils/generate-jwt-token");
6
+ /**
7
+ * Send password reset email using notification service
8
+ */
9
+ async function sendPasswordResetEmail(email, token, container) {
10
+ console.log("[reset-password] Sending password reset email directly...");
11
+ const notificationService = container.resolve(utils_1.Modules.NOTIFICATION);
12
+ if (!notificationService) {
13
+ console.error("[reset-password] Notification service is not configured");
14
+ return;
15
+ }
16
+ // Get storefront URL from environment or config
17
+ let storefrontUrl = "http://localhost:8000";
18
+ try {
19
+ const config = container.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
20
+ storefrontUrl =
21
+ process.env.STOREFRONT_URL ||
22
+ config?.projectConfig?.storefrontUrl ||
23
+ "http://localhost:8000";
24
+ }
25
+ catch (error) {
26
+ console.warn("[reset-password] Failed to resolve config, using default storefront URL:", error);
27
+ }
28
+ // Build reset URL with token and email as query parameters
29
+ const resetUrl = `${storefrontUrl}/reset-password?token=${encodeURIComponent(token)}&email=${encodeURIComponent(email)}`;
30
+ // Prepare HTML and text content
31
+ const htmlContent = `
32
+ <html>
33
+ <body>
34
+ <h2>Reset Your Password</h2>
35
+ <p>Hello,</p>
36
+ <p>You requested to reset your password. Click the link below to reset it:</p>
37
+ <p><a href="${resetUrl}">Reset Password</a></p>
38
+ <p>Or use this token: <code>${token}</code></p>
39
+ <p>This link will expire in 1 hour.</p>
40
+ <p>If you didn't request a password reset, please ignore this email.</p>
41
+ <p>Best regards,<br>Your Team</p>
42
+ </body>
43
+ </html>
44
+ `.trim();
45
+ const textContent = `Reset Your Password\n\nClick this link to reset your password: ${resetUrl}\n\nToken: ${token}\n\nThis link will expire in 1 hour.\n\nIf you didn't request a password reset, please ignore this email.`;
46
+ // Prepare email payload matching notification service structure
47
+ // Include multiple fields for different SMTP provider expectations
48
+ const payload = {
49
+ to: email,
50
+ channel: "email",
51
+ data: {
52
+ subject: "Reset Your Password",
53
+ email,
54
+ token,
55
+ reset_url: resetUrl,
56
+ expires_in: "1 hour",
57
+ html: htmlContent,
58
+ text: textContent,
59
+ },
60
+ // Root level fields for SMTP providers
61
+ html: htmlContent,
62
+ text: textContent,
63
+ body: htmlContent, // Some providers expect 'body' field
64
+ template: htmlContent, // Some providers expect 'template' field
65
+ subject: "Reset Your Password", // Include subject at root level too
66
+ };
67
+ // Log payload structure (sanitized for security)
68
+ console.log("[reset-password] Email payload structure:", {
69
+ to: payload.to,
70
+ channel: payload.channel,
71
+ subject: payload.subject,
72
+ hasHtml: !!payload.html,
73
+ hasText: !!payload.text,
74
+ hasBody: !!payload.body,
75
+ hasTemplate: !!payload.template,
76
+ dataKeys: Object.keys(payload.data || {}),
77
+ htmlLength: payload.html?.length || 0,
78
+ textLength: payload.text?.length || 0,
79
+ });
80
+ try {
81
+ if (typeof notificationService.create === "function") {
82
+ console.log("[reset-password] Using notificationService.create method");
83
+ await notificationService.create(payload);
84
+ console.log(`[reset-password] ✓ Password reset email sent successfully to ${email}`);
85
+ }
86
+ else if (typeof notificationService.createNotifications === "function") {
87
+ console.log("[reset-password] Using notificationService.createNotifications method");
88
+ await notificationService.createNotifications([payload]);
89
+ console.log(`[reset-password] ✓ Password reset email sent successfully to ${email}`);
90
+ }
91
+ else {
92
+ console.error("[reset-password] Notification service does not support sending notifications");
93
+ }
94
+ }
95
+ catch (error) {
96
+ console.error(`[reset-password] Failed to send password reset email to ${email}:`, error);
97
+ if (error instanceof Error) {
98
+ console.error("[reset-password] Error details:", {
99
+ message: error.message,
100
+ stack: error.stack,
101
+ });
102
+ }
103
+ throw error;
104
+ }
105
+ }
106
+ /**
107
+ * Password reset request endpoint
108
+ *
109
+ * This endpoint matches Medusa's built-in `/auth/{actor_type}/{provider}/reset-password` route behavior.
110
+ * It generates a password reset token and sends an email.
111
+ *
112
+ * Note: This custom route overrides Medusa's built-in route. The subscriber listens to
113
+ * `auth.password_reset` event (emitted by Medusa's built-in route) but since we're overriding
114
+ * the route, we send the email directly here.
115
+ *
116
+ * To use Medusa's built-in route instead, remove this file and update the subscriber
117
+ * to listen to `auth.password_reset` event.
118
+ */
119
+ const POST = async (req, res) => {
120
+ // Accept 'identifier' (Medusa's built-in route format) or 'email' for backward compatibility
121
+ const { identifier, email } = req.body;
122
+ const userEmail = identifier || email;
123
+ if (!userEmail || typeof userEmail !== "string" || !userEmail.trim()) {
124
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Email (identifier) is required");
125
+ }
126
+ const normalizedEmail = userEmail.toLowerCase().trim();
127
+ try {
128
+ // Find customer by email
129
+ const knex = req.scope.resolve(utils_1.ContainerRegistrationKeys.PG_CONNECTION);
130
+ if (!knex) {
131
+ throw new Error("Database connection not available");
132
+ }
133
+ const result = await knex.raw(`SELECT id FROM customer WHERE email = ? LIMIT 1`, [normalizedEmail]);
134
+ const row = result.rows?.[0] || result[0]?.[0];
135
+ const customer_id = row?.id;
136
+ // If customer doesn't exist, return success anyway (security: don't reveal if email exists)
137
+ // This matches Medusa's built-in route behavior
138
+ if (!customer_id) {
139
+ return res.status(201).json({});
140
+ }
141
+ // Get auth identity from provider_identity table
142
+ const providerIdentityResult = await knex.raw(`SELECT pi.id, pi.entity_id, pi.provider, ai.id as auth_identity_id
143
+ FROM provider_identity pi
144
+ LEFT JOIN auth_identity ai ON pi.auth_identity_id = ai.id
145
+ WHERE pi.entity_id = ? AND pi.provider = 'emailpass'
146
+ LIMIT 1`, [normalizedEmail]);
147
+ const providerIdentity = providerIdentityResult.rows?.[0] || providerIdentityResult[0]?.[0];
148
+ if (!providerIdentity || !providerIdentity.auth_identity_id) {
149
+ // Return success for security (don't reveal if email exists)
150
+ return res.status(201).json({});
151
+ }
152
+ // Get AUTH service to retrieve the full auth identity object
153
+ const authService = req.scope.resolve(utils_1.Modules.AUTH);
154
+ const authIdentity = await authService.retrieveAuthIdentity(providerIdentity.auth_identity_id);
155
+ if (!authIdentity) {
156
+ // Return success for security (don't reveal if email exists)
157
+ return res.status(201).json({});
158
+ }
159
+ // Generate reset token (JWT) with 1 hour expiration
160
+ // Using the same method Medusa's built-in route uses
161
+ const config = req.scope.resolve(utils_1.ContainerRegistrationKeys.CONFIG_MODULE);
162
+ const { http } = config.projectConfig;
163
+ const resetToken = (0, generate_jwt_token_1.generateJwtTokenForAuthIdentity)({
164
+ authIdentity,
165
+ actorType: "customer",
166
+ authProvider: "emailpass",
167
+ }, {
168
+ secret: http.jwtSecret,
169
+ expiresIn: "1h", // 1 hour expiration for reset token
170
+ options: http.jwtOptions,
171
+ });
172
+ // Send password reset email
173
+ // Note: Medusa's built-in route would emit 'auth.password_reset' event here
174
+ // Since we're overriding the route, we send the email directly
175
+ try {
176
+ await sendPasswordResetEmail(normalizedEmail, resetToken, req.scope);
177
+ }
178
+ catch (emailError) {
179
+ console.error("[reset-password] Failed to send email:", emailError);
180
+ // Continue anyway - don't reveal if email exists
181
+ }
182
+ // Return 201 (Created) to match Medusa's built-in route response
183
+ return res.status(201).json({});
184
+ }
185
+ catch (error) {
186
+ // Even on error, return success to prevent email enumeration attacks
187
+ // This matches Medusa's built-in route behavior
188
+ console.error("[reset-password] Error processing reset request:", error);
189
+ return res.status(201).json({});
190
+ }
191
+ };
192
+ exports.POST = POST;
193
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2F1dGgvY3VzdG9tZXIvZW1haWxwYXNzL3Jlc2V0LXBhc3N3b3JkL3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUNBLHFEQUEyRjtBQUUzRiwyRkFBb0c7QUFFcEc7O0dBRUc7QUFDSCxLQUFLLFVBQVUsc0JBQXNCLENBQ25DLEtBQWEsRUFDYixLQUFhLEVBQ2IsU0FBYztJQUVkLE9BQU8sQ0FBQyxHQUFHLENBQUMsMkRBQTJELENBQUMsQ0FBQTtJQUV4RSxNQUFNLG1CQUFtQixHQUFHLFNBQVMsQ0FBQyxPQUFPLENBQUMsZUFBTyxDQUFDLFlBQVksQ0FHakUsQ0FBQTtJQUVELElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1FBQ3pCLE9BQU8sQ0FBQyxLQUFLLENBQUMseURBQXlELENBQUMsQ0FBQTtRQUN4RSxPQUFNO0lBQ1IsQ0FBQztJQUVELGdEQUFnRDtJQUNoRCxJQUFJLGFBQWEsR0FBRyx1QkFBdUIsQ0FBQTtJQUMzQyxJQUFJLENBQUM7UUFDSCxNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsT0FBTyxDQUFDLGlDQUF5QixDQUFDLGFBQWEsQ0FBQyxDQUFBO1FBQ3pFLGFBQWE7WUFDWCxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWM7Z0JBQ3pCLE1BQU0sRUFBRSxhQUFxQixFQUFFLGFBQWE7Z0JBQzdDLHVCQUF1QixDQUFBO0lBQzNCLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YsT0FBTyxDQUFDLElBQUksQ0FBQywwRUFBMEUsRUFBRSxLQUFLLENBQUMsQ0FBQTtJQUNqRyxDQUFDO0lBRUQsMkRBQTJEO0lBQzNELE1BQU0sUUFBUSxHQUFHLEdBQUcsYUFBYSx5QkFBeUIsa0JBQWtCLENBQUMsS0FBSyxDQUFDLFVBQVUsa0JBQWtCLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQTtJQUV4SCxn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
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.POST = void 0;
4
+ const utils_1 = require("@medusajs/framework/utils");
5
+ /**
6
+ * Password reset completion endpoint
7
+ *
8
+ * This endpoint uses Medusa's built-in AUTH module updateProvider method
9
+ * to update the customer's password. The AUTH module handles:
10
+ * 1. Token validation (from Authorization header)
11
+ * 2. Password hashing
12
+ * 3. Database updates
13
+ *
14
+ * This matches Medusa's built-in `/auth/{actor_type}/{provider}/update` route behavior.
15
+ */
16
+ const POST = async (req, res) => {
17
+ const { email, password } = req.body;
18
+ // Get token from Authorization header (required by Medusa's built-in route)
19
+ const resetToken = req.headers.authorization?.replace("Bearer ", "");
20
+ if (!resetToken) {
21
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Reset token is required. Provide it in the 'Authorization: Bearer {token}' header");
22
+ }
23
+ if (!email || typeof email !== "string" || !email.trim()) {
24
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Email is required");
25
+ }
26
+ if (!password || typeof password !== "string" || password.length < 8) {
27
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Password is required and must be at least 8 characters");
28
+ }
29
+ const normalizedEmail = email.toLowerCase().trim();
30
+ try {
31
+ // Get AUTH service
32
+ const authService = req.scope.resolve(utils_1.Modules.AUTH);
33
+ // Use Medusa's built-in updateProvider method
34
+ // This method validates the token, hashes the password, and updates it in the database
35
+ // Pass the token in the data object (matching SDK behavior)
36
+ const result = await authService.updateProvider("emailpass", {
37
+ entity_id: normalizedEmail,
38
+ password: password,
39
+ token: resetToken,
40
+ });
41
+ // updateProvider returns the updated auth identity on success
42
+ if (!result) {
43
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNAUTHORIZED, "Failed to reset password. Invalid or expired token.");
44
+ }
45
+ return res.status(200).json({
46
+ message: "Password reset successfully",
47
+ success: true,
48
+ });
49
+ }
50
+ catch (error) {
51
+ // Re-throw MedusaError as-is
52
+ if (error instanceof utils_1.MedusaError) {
53
+ throw error;
54
+ }
55
+ // Handle unexpected errors
56
+ console.error("[reset-password-complete] Unexpected error:", error);
57
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, `Failed to reset password: ${error instanceof Error ? error.message : String(error)}`);
58
+ }
59
+ };
60
+ exports.POST = POST;
61
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL2F1dGgvY3VzdG9tZXIvZW1haWxwYXNzL3VwZGF0ZS9yb3V0ZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFDQSxxREFBZ0U7QUFFaEU7Ozs7Ozs7Ozs7R0FVRztBQUNJLE1BQU0sSUFBSSxHQUFHLEtBQUssRUFBRSxHQUFrQixFQUFFLEdBQW1CLEVBQUUsRUFBRTtJQUNwRSxNQUFNLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxHQUFHLEdBQUcsQ0FBQyxJQUcvQixDQUFBO0lBRUQsNEVBQTRFO0lBQzVFLE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUE7SUFFcEUsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2hCLE1BQU0sSUFBSSxtQkFBVyxDQUNuQixtQkFBVyxDQUFDLEtBQUssQ0FBQyxZQUFZLEVBQzlCLG1GQUFtRixDQUNwRixDQUFBO0lBQ0gsQ0FBQztJQUVELElBQUksQ0FBQyxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7UUFDekQsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsbUJBQW1CLENBQ3BCLENBQUE7SUFDSCxDQUFDO0lBRUQsSUFBSSxDQUFDLFFBQVEsSUFBSSxPQUFPLFFBQVEsS0FBSyxRQUFRLElBQUksUUFBUSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNyRSxNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5Qix3REFBd0QsQ0FDekQsQ0FBQTtJQUNILENBQUM7SUFFRCxNQUFNLGVBQWUsR0FBRyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUE7SUFFbEQsSUFBSSxDQUFDO1FBQ0gsbUJBQW1CO1FBQ25CLE1BQU0sV0FBVyxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGVBQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUVuRCw4Q0FBOEM7UUFDOUMsdUZBQXVGO1FBQ3ZGLDREQUE0RDtRQUM1RCxNQUFNLE1BQU0sR0FBRyxNQUFNLFdBQVcsQ0FBQyxjQUFjLENBQzdDLFdBQVcsRUFDWDtZQUNFLFNBQVMsRUFBRSxlQUFlO1lBQzFCLFFBQVEsRUFBRSxRQUFRO1lBQ2xCLEtBQUssRUFBRSxVQUFVO1NBQ2xCLENBQ0YsQ0FBQTtRQUVELDhEQUE4RDtRQUM5RCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDWixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5QixxREFBcUQsQ0FDdEQsQ0FBQTtRQUNILENBQUM7UUFFRCxPQUFPLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQzFCLE9BQU8sRUFBRSw2QkFBNkI7WUFDdEMsT0FBTyxFQUFFLElBQUk7U0FDZCxDQUFDLENBQUE7SUFDSixDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLDZCQUE2QjtRQUM3QixJQUFJLEtBQUssWUFBWSxtQkFBVyxFQUFFLENBQUM7WUFDakMsTUFBTSxLQUFLLENBQUE7UUFDYixDQUFDO1FBRUQsMkJBQTJCO1FBQzNCLE9BQU8sQ0FBQyxLQUFLLENBQUMsNkNBQTZDLEVBQUUsS0FBSyxDQUFDLENBQUE7UUFDbkUsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLGdCQUFnQixFQUNsQyw2QkFBNkIsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQ3RGLENBQUE7SUFDSCxDQUFDO0FBQ0gsQ0FBQyxDQUFBO0FBekVZLFFBQUEsSUFBSSxRQXlFaEIifQ==
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.POST = void 0;
7
+ const utils_1 = require("@medusajs/framework/utils");
8
+ const change_password_1 = __importDefault(require("../../../../workflows/change-password"));
9
+ const POST = async (req, res) => {
10
+ // Get customer from auth context
11
+ const authContext = req.auth_context;
12
+ const customerId = authContext?.actor_id || authContext?.user_id;
13
+ if (!customerId) {
14
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNAUTHORIZED, "Authentication required");
15
+ }
16
+ const { old_password, new_password, confirm_password } = req.body;
17
+ if (!old_password) {
18
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Current password is required");
19
+ }
20
+ if (!new_password) {
21
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "New password is required");
22
+ }
23
+ if (!confirm_password) {
24
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Confirm password is required");
25
+ }
26
+ try {
27
+ // Execute change password workflow (validates password, verifies old password, and updates password)
28
+ const { result } = await (0, change_password_1.default)(req.scope).run({
29
+ input: {
30
+ customer_id: customerId,
31
+ old_password,
32
+ new_password,
33
+ confirm_password,
34
+ },
35
+ });
36
+ return res.status(200).json({
37
+ message: "Password changed successfully",
38
+ customer_id: result.customer_id,
39
+ });
40
+ }
41
+ catch (error) {
42
+ // Re-throw MedusaError as-is
43
+ if (error instanceof utils_1.MedusaError) {
44
+ throw error;
45
+ }
46
+ // Handle unexpected errors
47
+ console.error("[change-password] Unexpected error:", error);
48
+ throw new utils_1.MedusaError(utils_1.MedusaError.Types.UNEXPECTED_STATE, "Failed to change password");
49
+ }
50
+ };
51
+ exports.POST = POST;
52
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2N1c3RvbWVycy9jaGFuZ2UtcGFzc3dvcmQvcm91dGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQ0EscURBQXVEO0FBQ3ZELDRGQUEwRTtBQUVuRSxNQUFNLElBQUksR0FBRyxLQUFLLEVBQUUsR0FBa0IsRUFBRSxHQUFtQixFQUFFLEVBQUU7SUFDcEUsaUNBQWlDO0lBQ2pDLE1BQU0sV0FBVyxHQUFJLEdBQWtFLENBQUMsWUFBWSxDQUFBO0lBQ3BHLE1BQU0sVUFBVSxHQUFHLFdBQVcsRUFBRSxRQUFRLElBQUksV0FBVyxFQUFFLE9BQU8sQ0FBQTtJQUVoRSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDaEIsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIseUJBQXlCLENBQzFCLENBQUE7SUFDSCxDQUFDO0lBRUQsTUFBTSxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsZ0JBQWdCLEVBQUUsR0FBRyxHQUFHLENBQUMsSUFJNUQsQ0FBQTtJQUVELElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNsQixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5Qiw4QkFBOEIsQ0FDL0IsQ0FBQTtJQUNILENBQUM7SUFFRCxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDbEIsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsMEJBQTBCLENBQzNCLENBQUE7SUFDSCxDQUFDO0lBRUQsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDdEIsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsOEJBQThCLENBQy9CLENBQUE7SUFDSCxDQUFDO0lBRUQsSUFBSSxDQUFDO1FBQ0gscUdBQXFHO1FBQ3JHLE1BQU0sRUFBRSxNQUFNLEVBQUUsR0FBRyxNQUFNLElBQUEseUJBQXNCLEVBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQztZQUM3RCxLQUFLLEVBQUU7Z0JBQ0wsV0FBVyxFQUFFLFVBQVU7Z0JBQ3ZCLFlBQVk7Z0JBQ1osWUFBWTtnQkFDWixnQkFBZ0I7YUFDakI7U0FDRixDQUFDLENBQUE7UUFFRixPQUFPLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQzFCLE9BQU8sRUFBRSwrQkFBK0I7WUFDeEMsV0FBVyxFQUFFLE1BQU0sQ0FBQyxXQUFXO1NBQ2hDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YsNkJBQTZCO1FBQzdCLElBQUksS0FBSyxZQUFZLG1CQUFXLEVBQUUsQ0FBQztZQUNqQyxNQUFNLEtBQUssQ0FBQTtRQUNiLENBQUM7UUFFRCwyQkFBMkI7UUFDM0IsT0FBTyxDQUFDLEtBQUssQ0FBQyxxQ0FBcUMsRUFBRSxLQUFLLENBQUMsQ0FBQTtRQUMzRCxNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEVBQ2xDLDJCQUEyQixDQUM1QixDQUFBO0lBQ0gsQ0FBQztBQUNILENBQUMsQ0FBQTtBQW5FWSxRQUFBLElBQUksUUFtRWhCIn0=
@@ -9,7 +9,6 @@ const otp_verification_1 = require("../../../../../modules/otp-verification");
9
9
  const otp_verification_2 = require("../../../../../modules/otp-verification/models/otp-verification");
10
10
  const verify_email_1 = __importDefault(require("../../../../../workflows/verify-email"));
11
11
  const verify_phone_1 = __importDefault(require("../../../../../workflows/verify-phone"));
12
- const generate_password_reset_token_1 = __importDefault(require("../../../../../workflows/generate-password-reset-token"));
13
12
  const POST = async (req, res) => {
14
13
  const { token, code } = req.body;
15
14
  if (!token) {
@@ -54,22 +53,10 @@ const POST = async (req, res) => {
54
53
  phone_verified: workflowResult.phone_verified,
55
54
  };
56
55
  }
57
- else if (verifyResult.type === otp_verification_2.OtpPurpose.FORGOT_PASSWORD) {
58
- const { result: workflowResult } = await (0, generate_password_reset_token_1.default)(req.scope).run({
59
- input: {
60
- customer_id: verifyResult.customer_id,
61
- },
62
- });
63
- result = {
64
- verified: true,
65
- reset_token: workflowResult.token,
66
- expires_in: workflowResult.expires_in,
67
- };
68
- }
69
56
  else {
70
57
  throw new utils_1.MedusaError(utils_1.MedusaError.Types.INVALID_DATA, "Invalid verification type");
71
58
  }
72
59
  return res.status(200).json(result);
73
60
  };
74
61
  exports.POST = POST;
75
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2N1c3RvbWVycy9vdHAvdmVyaWZ5L3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBLHFEQUdrQztBQUNsQyw4RUFBaUY7QUFFakYsc0dBQTRGO0FBQzVGLHlGQUF1RTtBQUN2RSx5RkFBdUU7QUFDdkUsMkhBQXVHO0FBRWhHLE1BQU0sSUFBSSxHQUFHLEtBQUssRUFBRSxHQUFrQixFQUFFLEdBQW1CLEVBQUUsRUFBRTtJQUNwRSxNQUFNLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxHQUFHLEdBQUcsQ0FBQyxJQUczQixDQUFBO0lBRUQsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ1gsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsbUJBQW1CLENBQ3BCLENBQUE7SUFDSCxDQUFDO0lBRUQsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ1YsTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsc0JBQXNCLENBQ3ZCLENBQUE7SUFDSCxDQUFDO0lBRUQsOEJBQThCO0lBQzlCLE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUNsQywwQ0FBdUIsQ0FDRSxDQUFBO0lBRTNCLDZCQUE2QjtJQUM3QixNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxpQ0FBeUIsQ0FBQyxhQUFhLENBQUMsQ0FBQTtJQUN6RSxNQUFNLFNBQVMsR0FBSSxNQUFNLEVBQUUsYUFBcUIsRUFBRSxJQUFJLEVBQUUsU0FBUyxJQUFJLGFBQWEsQ0FBQTtJQUVsRixhQUFhO0lBQ2IsTUFBTSxZQUFZLEdBQUcsTUFBTSxVQUFVLENBQUMsU0FBUyxDQUM3QztRQUNFLEtBQUs7UUFDTCxJQUFJO0tBQ0wsRUFDRCxTQUFTLENBQ1YsQ0FBQTtJQUVELGlDQUFpQztJQUNqQyxJQUFJLE1BQVcsQ0FBQTtJQUVmLElBQUksWUFBWSxDQUFDLElBQUksS0FBSyw2QkFBVSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDeEQsTUFBTSxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUUsR0FBRyxNQUFNLElBQUEsc0JBQW1CLEVBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQztZQUMxRSxLQUFLLEVBQUU7Z0JBQ0wsV0FBVyxFQUFFLFlBQVksQ0FBQyxXQUFXO2FBQ3RDO1NBQ0YsQ0FBQyxDQUFBO1FBQ0YsTUFBTSxHQUFHO1lBQ1AsUUFBUSxFQUFFLElBQUk7WUFDZCxRQUFRLEVBQUUsY0FBYyxDQUFDLFFBQVE7WUFDakMsY0FBYyxFQUFFLGNBQWMsQ0FBQyxjQUFjO1NBQzlDLENBQUE7SUFDSCxDQUFDO1NBQU0sSUFBSSxZQUFZLENBQUMsSUFBSSxLQUFLLDZCQUFVLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMvRCxNQUFNLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxHQUFHLE1BQU0sSUFBQSxzQkFBbUIsRUFBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDO1lBQzFFLEtBQUssRUFBRTtnQkFDTCxXQUFXLEVBQUUsWUFBWSxDQUFDLFdBQVc7YUFDdEM7U0FDRixDQUFDLENBQUE7UUFDRixNQUFNLEdBQUc7WUFDUCxRQUFRLEVBQUUsSUFBSTtZQUNkLFFBQVEsRUFBRSxjQUFjLENBQUMsUUFBUTtZQUNqQyxjQUFjLEVBQUUsY0FBYyxDQUFDLGNBQWM7U0FDOUMsQ0FBQTtJQUNILENBQUM7U0FBTSxJQUFJLFlBQVksQ0FBQyxJQUFJLEtBQUssNkJBQVUsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUM1RCxNQUFNLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxHQUFHLE1BQU0sSUFBQSx1Q0FBa0MsRUFBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDO1lBQ3pGLEtBQUssRUFBRTtnQkFDTCxXQUFXLEVBQUUsWUFBWSxDQUFDLFdBQVc7YUFDdEM7U0FDRixDQUFDLENBQUE7UUFDRixNQUFNLEdBQUc7WUFDUCxRQUFRLEVBQUUsSUFBSTtZQUNkLFdBQVcsRUFBRSxjQUFjLENBQUMsS0FBSztZQUNqQyxVQUFVLEVBQUUsY0FBYyxDQUFDLFVBQVU7U0FDdEMsQ0FBQTtJQUNILENBQUM7U0FBTSxDQUFDO1FBQ04sTUFBTSxJQUFJLG1CQUFXLENBQ25CLG1CQUFXLENBQUMsS0FBSyxDQUFDLFlBQVksRUFDOUIsMkJBQTJCLENBQzVCLENBQUE7SUFDSCxDQUFDO0lBRUQsT0FBTyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQTtBQUNyQyxDQUFDLENBQUE7QUFsRlksUUFBQSxJQUFJLFFBa0ZoQiJ9
62
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicm91dGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBpL3N0b3JlL2N1c3RvbWVycy9vdHAvdmVyaWZ5L3JvdXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUNBLHFEQUdrQztBQUNsQyw4RUFBaUY7QUFFakYsc0dBQTRGO0FBQzVGLHlGQUF1RTtBQUN2RSx5RkFBdUU7QUFFaEUsTUFBTSxJQUFJLEdBQUcsS0FBSyxFQUFFLEdBQWtCLEVBQUUsR0FBbUIsRUFBRSxFQUFFO0lBQ3BFLE1BQU0sRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEdBQUcsR0FBRyxDQUFDLElBRzNCLENBQUE7SUFFRCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDWCxNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5QixtQkFBbUIsQ0FDcEIsQ0FBQTtJQUNILENBQUM7SUFFRCxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDVixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5QixzQkFBc0IsQ0FDdkIsQ0FBQTtJQUNILENBQUM7SUFFRCw4QkFBOEI7SUFDOUIsTUFBTSxVQUFVLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQ2xDLDBDQUF1QixDQUNFLENBQUE7SUFFM0IsNkJBQTZCO0lBQzdCLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLGlDQUF5QixDQUFDLGFBQWEsQ0FBQyxDQUFBO0lBQ3pFLE1BQU0sU0FBUyxHQUFJLE1BQU0sRUFBRSxhQUFxQixFQUFFLElBQUksRUFBRSxTQUFTLElBQUksYUFBYSxDQUFBO0lBRWxGLGFBQWE7SUFDYixNQUFNLFlBQVksR0FBRyxNQUFNLFVBQVUsQ0FBQyxTQUFTLENBQzdDO1FBQ0UsS0FBSztRQUNMLElBQUk7S0FDTCxFQUNELFNBQVMsQ0FDVixDQUFBO0lBRUQsaUNBQWlDO0lBQ2pDLElBQUksTUFBVyxDQUFBO0lBRWYsSUFBSSxZQUFZLENBQUMsSUFBSSxLQUFLLDZCQUFVLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUN4RCxNQUFNLEVBQUUsTUFBTSxFQUFFLGNBQWMsRUFBRSxHQUFHLE1BQU0sSUFBQSxzQkFBbUIsRUFBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDO1lBQzFFLEtBQUssRUFBRTtnQkFDTCxXQUFXLEVBQUUsWUFBWSxDQUFDLFdBQVc7YUFDdEM7U0FDRixDQUFDLENBQUE7UUFDRixNQUFNLEdBQUc7WUFDUCxRQUFRLEVBQUUsSUFBSTtZQUNkLFFBQVEsRUFBRSxjQUFjLENBQUMsUUFBUTtZQUNqQyxjQUFjLEVBQUUsY0FBYyxDQUFDLGNBQWM7U0FDOUMsQ0FBQTtJQUNILENBQUM7U0FBTSxJQUFJLFlBQVksQ0FBQyxJQUFJLEtBQUssNkJBQVUsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1FBQy9ELE1BQU0sRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLEdBQUcsTUFBTSxJQUFBLHNCQUFtQixFQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUM7WUFDMUUsS0FBSyxFQUFFO2dCQUNMLFdBQVcsRUFBRSxZQUFZLENBQUMsV0FBVzthQUN0QztTQUNGLENBQUMsQ0FBQTtRQUNGLE1BQU0sR0FBRztZQUNQLFFBQVEsRUFBRSxJQUFJO1lBQ2QsUUFBUSxFQUFFLGNBQWMsQ0FBQyxRQUFRO1lBQ2pDLGNBQWMsRUFBRSxjQUFjLENBQUMsY0FBYztTQUM5QyxDQUFBO0lBQ0gsQ0FBQztTQUFNLENBQUM7UUFDTixNQUFNLElBQUksbUJBQVcsQ0FDbkIsbUJBQVcsQ0FBQyxLQUFLLENBQUMsWUFBWSxFQUM5QiwyQkFBMkIsQ0FDNUIsQ0FBQTtJQUNILENBQUM7SUFFRCxPQUFPLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFBO0FBQ3JDLENBQUMsQ0FBQTtBQXZFWSxRQUFBLElBQUksUUF1RWhCIn0=
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getClientRequest = exports.buildHeaders = exports.normalizeBaseUrl = void 0;
4
+ const normalizeBaseUrl = (baseUrl) => {
5
+ if (!baseUrl) {
6
+ return "";
7
+ }
8
+ return baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
9
+ };
10
+ exports.normalizeBaseUrl = normalizeBaseUrl;
11
+ const buildHeaders = (options) => {
12
+ const headers = {
13
+ "Content-Type": "application/json",
14
+ ...(options.headers ?? {}),
15
+ };
16
+ const hasPublishableHeader = Object.keys(headers).some((key) => key.toLowerCase() === "x-publishable-api-key");
17
+ if (options.publishableApiKey && !hasPublishableHeader) {
18
+ headers["x-publishable-api-key"] = options.publishableApiKey;
19
+ }
20
+ return headers;
21
+ };
22
+ exports.buildHeaders = buildHeaders;
23
+ const getClientRequest = (client) => {
24
+ if (!client) {
25
+ return undefined;
26
+ }
27
+ if ("request" in client && typeof client.request === "function") {
28
+ return client.request.bind(client);
29
+ }
30
+ if ("client" in client && typeof client.client?.request === "function") {
31
+ return client.client.request.bind(client.client);
32
+ }
33
+ return undefined;
34
+ };
35
+ exports.getClientRequest = getClientRequest;
36
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1jbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaGVscGVycy9iYXNlLWNsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFvQ08sTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLE9BQWdCLEVBQUUsRUFBRTtJQUNuRCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDYixPQUFPLEVBQUUsQ0FBQTtJQUNYLENBQUM7SUFDRCxPQUFPLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQTtBQUMvRCxDQUFDLENBQUE7QUFMWSxRQUFBLGdCQUFnQixvQkFLNUI7QUFFTSxNQUFNLFlBQVksR0FBRyxDQUFDLE9BQStCLEVBQUUsRUFBRTtJQUM5RCxNQUFNLE9BQU8sR0FBMkI7UUFDdEMsY0FBYyxFQUFFLGtCQUFrQjtRQUNsQyxHQUFHLENBQUMsT0FBTyxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQUM7S0FDM0IsQ0FBQTtJQUVELE1BQU0sb0JBQW9CLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQ3BELENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLEtBQUssdUJBQXVCLENBQ3ZELENBQUE7SUFFRCxJQUFJLE9BQU8sQ0FBQyxpQkFBaUIsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDdkQsT0FBTyxDQUFDLHVCQUF1QixDQUFDLEdBQUcsT0FBTyxDQUFDLGlCQUFpQixDQUFBO0lBQzlELENBQUM7SUFFRCxPQUFPLE9BQU8sQ0FBQTtBQUNoQixDQUFDLENBQUE7QUFmWSxRQUFBLFlBQVksZ0JBZXhCO0FBRU0sTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLE1BQXlCLEVBQUUsRUFBRTtJQUM1RCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDWixPQUFPLFNBQVMsQ0FBQTtJQUNsQixDQUFDO0lBRUQsSUFBSSxTQUFTLElBQUksTUFBTSxJQUFJLE9BQU8sTUFBTSxDQUFDLE9BQU8sS0FBSyxVQUFVLEVBQUUsQ0FBQztRQUNoRSxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQ3BDLENBQUM7SUFFRCxJQUFJLFFBQVEsSUFBSSxNQUFNLElBQUksT0FBTyxNQUFNLENBQUMsTUFBTSxFQUFFLE9BQU8sS0FBSyxVQUFVLEVBQUUsQ0FBQztRQUN2RSxPQUFPLE1BQU0sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDbEQsQ0FBQztJQUVELE9BQU8sU0FBUyxDQUFBO0FBQ2xCLENBQUMsQ0FBQTtBQWRZLFFBQUEsZ0JBQWdCLG9CQWM1QiJ9
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCompletePasswordReset = exports.completePasswordReset = exports.createRequestPasswordReset = exports.requestPasswordReset = exports.getClientRequest = exports.buildHeaders = exports.normalizeBaseUrl = void 0;
4
+ // Base client utilities
5
+ var base_client_1 = require("./base-client");
6
+ Object.defineProperty(exports, "normalizeBaseUrl", { enumerable: true, get: function () { return base_client_1.normalizeBaseUrl; } });
7
+ Object.defineProperty(exports, "buildHeaders", { enumerable: true, get: function () { return base_client_1.buildHeaders; } });
8
+ Object.defineProperty(exports, "getClientRequest", { enumerable: true, get: function () { return base_client_1.getClientRequest; } });
9
+ // Password reset helpers
10
+ var reset_password_1 = require("./reset-password");
11
+ Object.defineProperty(exports, "requestPasswordReset", { enumerable: true, get: function () { return reset_password_1.requestPasswordReset; } });
12
+ Object.defineProperty(exports, "createRequestPasswordReset", { enumerable: true, get: function () { return reset_password_1.createRequestPasswordReset; } });
13
+ var reset_password_2 = require("./reset-password");
14
+ Object.defineProperty(exports, "completePasswordReset", { enumerable: true, get: function () { return reset_password_2.completePasswordReset; } });
15
+ Object.defineProperty(exports, "createCompletePasswordReset", { enumerable: true, get: function () { return reset_password_2.createCompletePasswordReset; } });
16
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaGVscGVycy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx3QkFBd0I7QUFDeEIsNkNBTXNCO0FBSHBCLCtHQUFBLGdCQUFnQixPQUFBO0FBQ2hCLDJHQUFBLFlBQVksT0FBQTtBQUNaLCtHQUFBLGdCQUFnQixPQUFBO0FBR2xCLHlCQUF5QjtBQUN6QixtREFNeUI7QUFGdkIsc0hBQUEsb0JBQW9CLE9BQUE7QUFDcEIsNEhBQUEsMEJBQTBCLE9BQUE7QUFHNUIsbURBTXlCO0FBRnZCLHVIQUFBLHFCQUFxQixPQUFBO0FBQ3JCLDZIQUFBLDJCQUEyQixPQUFBIn0=
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createCompletePasswordReset = exports.createRequestPasswordReset = exports.completePasswordReset = exports.requestPasswordReset = void 0;
4
+ const base_client_1 = require("./base-client");
5
+ const RESET_PASSWORD_ENDPOINT = "/auth/customer/emailpass/reset-password";
6
+ const COMPLETE_PASSWORD_RESET_ENDPOINT = "/auth/customer/emailpass/update";
7
+ const resolveEndpoint = (defaultEndpoint, endpoint) => endpoint?.startsWith("/") ? endpoint : defaultEndpoint;
8
+ /**
9
+ * Request a password reset for a customer
10
+ *
11
+ * This function calls the password reset endpoint which generates a JWT reset token
12
+ * and sends a password reset email to the customer.
13
+ *
14
+ * The API returns an empty object `{}` with 201 status for security reasons
15
+ * (doesn't reveal if email exists to prevent email enumeration attacks).
16
+ *
17
+ * @param input - Password reset request input
18
+ * @param options - Transport options (baseUrl, client, publishableApiKey, etc.)
19
+ * @returns Promise resolving to the reset request response (empty object on success)
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * import { requestPasswordReset } from "customer-registration/helpers"
24
+ *
25
+ * // Basic usage
26
+ * const result = await requestPasswordReset(
27
+ * { email: "customer@example.com" },
28
+ * { baseUrl: "https://store.example.com", publishableApiKey: "pk_..." }
29
+ * )
30
+ *
31
+ * // With Medusa SDK client
32
+ * import { sdk } from "@medusajs/js-sdk"
33
+ * const result = await requestPasswordReset(
34
+ * { email: "customer@example.com" },
35
+ * { client: sdk }
36
+ * )
37
+ * ```
38
+ */
39
+ const requestPasswordReset = async (input, options = {}) => {
40
+ const endpoint = resolveEndpoint(RESET_PASSWORD_ENDPOINT, input.endpoint);
41
+ const payload = {
42
+ email: input.email.toLowerCase().trim(),
43
+ };
44
+ const clientRequest = (0, base_client_1.getClientRequest)(options.client);
45
+ if (clientRequest) {
46
+ const headers = (0, base_client_1.buildHeaders)(options);
47
+ const raw = await clientRequest(endpoint, {
48
+ method: "POST",
49
+ body: JSON.stringify(payload),
50
+ headers,
51
+ });
52
+ // Accept empty object {} as valid response (API returns {} for security)
53
+ if (raw === null || (typeof raw !== "object" && raw !== undefined)) {
54
+ throw new Error("Invalid response from password reset endpoint");
55
+ }
56
+ // Return empty object or the response as-is
57
+ return (raw || {});
58
+ }
59
+ const fetchImpl = options.fetchImpl ?? globalThis.fetch;
60
+ if (!fetchImpl) {
61
+ throw new Error("No fetch implementation available. Provide `fetchImpl` or a Medusa client.");
62
+ }
63
+ const url = `${(0, base_client_1.normalizeBaseUrl)(options.baseUrl)}${endpoint}`;
64
+ const headers = (0, base_client_1.buildHeaders)(options);
65
+ const response = await fetchImpl(url || endpoint, {
66
+ method: "POST",
67
+ headers,
68
+ body: JSON.stringify(payload),
69
+ });
70
+ if (!response.ok) {
71
+ const body = await response.text();
72
+ throw new Error(body || `Failed to request password reset (status ${response.status})`);
73
+ }
74
+ // Handle empty response (204 No Content) or empty JSON object
75
+ const contentType = response.headers.get("content-type");
76
+ if (contentType && contentType.includes("application/json")) {
77
+ const json = await response.json();
78
+ // Accept empty object {} as valid response
79
+ return (json || {});
80
+ }
81
+ // If no content, return empty object
82
+ return {};
83
+ };
84
+ exports.requestPasswordReset = requestPasswordReset;
85
+ /**
86
+ * Complete a password reset with a new password
87
+ *
88
+ * This function calls the password reset completion endpoint which validates
89
+ * the reset token and updates the customer's password using Medusa's AUTH module
90
+ * `updateProvider` method.
91
+ *
92
+ * The token is sent in both:
93
+ * - The request body (`token` field)
94
+ * - The `Authorization: Bearer {token}` header (automatically added)
95
+ *
96
+ * The route reads the token from the Authorization header and passes it to
97
+ * `updateProvider`, which handles token validation, password hashing, and database updates.
98
+ *
99
+ * @param input - Password reset completion input
100
+ * @param options - Transport options (baseUrl, client, publishableApiKey, etc.)
101
+ * @returns Promise resolving to the reset completion response
102
+ *
103
+ * @example
104
+ * ```typescript
105
+ * import { completePasswordReset } from "customer-registration/helpers"
106
+ *
107
+ * // Basic usage with token in input
108
+ * const result = await completePasswordReset(
109
+ * {
110
+ * email: "customer@example.com",
111
+ * password: "NewSecurePassword123!",
112
+ * token: "reset_token_from_email"
113
+ * },
114
+ * { baseUrl: "https://store.example.com", publishableApiKey: "pk_..." }
115
+ * )
116
+ *
117
+ * // With token in Authorization header (helper automatically adds it)
118
+ * const result = await completePasswordReset(
119
+ * {
120
+ * email: "customer@example.com",
121
+ * password: "NewSecurePassword123!",
122
+ * token: "reset_token_from_email"
123
+ * },
124
+ * {
125
+ * baseUrl: "https://store.example.com",
126
+ * publishableApiKey: "pk_...",
127
+ * headers: {
128
+ * "Authorization": "Bearer reset_token_from_email"
129
+ * }
130
+ * }
131
+ * )
132
+ *
133
+ * // With Medusa SDK client
134
+ * import { sdk } from "@medusajs/js-sdk"
135
+ * const result = await completePasswordReset(
136
+ * {
137
+ * email: "customer@example.com",
138
+ * password: "NewSecurePassword123!",
139
+ * token: "reset_token_from_email"
140
+ * },
141
+ * { client: sdk }
142
+ * )
143
+ * ```
144
+ */
145
+ const completePasswordReset = async (input, options = {}) => {
146
+ const endpoint = resolveEndpoint(COMPLETE_PASSWORD_RESET_ENDPOINT, input.endpoint);
147
+ const payload = {
148
+ email: input.email.toLowerCase().trim(),
149
+ password: input.password,
150
+ token: input.token,
151
+ };
152
+ const clientRequest = (0, base_client_1.getClientRequest)(options.client);
153
+ if (clientRequest) {
154
+ const headers = (0, base_client_1.buildHeaders)(options);
155
+ // Add Authorization header if token is provided and not already in headers
156
+ if (input.token && !headers.authorization) {
157
+ headers.authorization = `Bearer ${input.token}`;
158
+ }
159
+ const raw = await clientRequest(endpoint, {
160
+ method: "POST",
161
+ body: JSON.stringify(payload),
162
+ headers,
163
+ });
164
+ if (!raw || typeof raw !== "object" || !("success" in raw)) {
165
+ throw new Error("Invalid response from password reset completion endpoint");
166
+ }
167
+ return raw;
168
+ }
169
+ const fetchImpl = options.fetchImpl ?? globalThis.fetch;
170
+ if (!fetchImpl) {
171
+ throw new Error("No fetch implementation available. Provide `fetchImpl` or a Medusa client.");
172
+ }
173
+ const url = `${(0, base_client_1.normalizeBaseUrl)(options.baseUrl)}${endpoint}`;
174
+ const headers = (0, base_client_1.buildHeaders)(options);
175
+ // Add Authorization header if token is provided and not already in headers
176
+ if (input.token && !headers.authorization) {
177
+ headers.authorization = `Bearer ${input.token}`;
178
+ }
179
+ const response = await fetchImpl(url || endpoint, {
180
+ method: "POST",
181
+ headers,
182
+ body: JSON.stringify(payload),
183
+ });
184
+ if (!response.ok) {
185
+ const body = await response.text();
186
+ throw new Error(body || `Failed to complete password reset (status ${response.status})`);
187
+ }
188
+ const json = await response.json();
189
+ if (!json || typeof json !== "object" || !("success" in json)) {
190
+ throw new Error("Invalid response format from password reset completion endpoint");
191
+ }
192
+ return json;
193
+ };
194
+ exports.completePasswordReset = completePasswordReset;
195
+ /**
196
+ * Factory creator for preconfigured password reset request helper
197
+ */
198
+ const createRequestPasswordReset = (options = {}) => (input) => (0, exports.requestPasswordReset)(input, options);
199
+ exports.createRequestPasswordReset = createRequestPasswordReset;
200
+ /**
201
+ * Factory creator for preconfigured password reset completion helper
202
+ */
203
+ const createCompletePasswordReset = (options = {}) => (input) => (0, exports.completePasswordReset)(input, options);
204
+ exports.createCompletePasswordReset = createCompletePasswordReset;
205
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzZXQtcGFzc3dvcmQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaGVscGVycy9yZXNldC1wYXNzd29yZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrQ0FLc0I7QUFFdEIsTUFBTSx1QkFBdUIsR0FBRyx5Q0FBeUMsQ0FBQTtBQUN6RSxNQUFNLGdDQUFnQyxHQUFHLGlDQUFpQyxDQUFBO0FBRTFFLE1BQU0sZUFBZSxHQUFHLENBQUMsZUFBdUIsRUFBRSxRQUFpQixFQUFFLEVBQUUsQ0FDckUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxlQUFlLENBQUE7QUFnQ3hEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4Qkc7QUFDSSxNQUFNLG9CQUFvQixHQUFHLEtBQUssRUFDdkMsS0FBZ0MsRUFDaEMsVUFBdUMsRUFBRSxFQUNGLEVBQUU7SUFDekMsTUFBTSxRQUFRLEdBQUcsZUFBZSxDQUFDLHVCQUF1QixFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQTtJQUN6RSxNQUFNLE9BQU8sR0FBRztRQUNkLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDLElBQUksRUFBRTtLQUN4QyxDQUFBO0lBRUQsTUFBTSxhQUFhLEdBQUcsSUFBQSw4QkFBZ0IsRUFBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUE7SUFDdEQsSUFBSSxhQUFhLEVBQUUsQ0FBQztRQUNsQixNQUFNLE9BQU8sR0FBRyxJQUFBLDBCQUFZLEVBQUMsT0FBTyxDQUFDLENBQUE7UUFDckMsTUFBTSxHQUFHLEdBQUcsTUFBTSxhQUFhLENBQUMsUUFBUSxFQUFFO1lBQ3hDLE1BQU0sRUFBRSxNQUFNO1lBQ2QsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDO1lBQzdCLE9BQU87U0FDUixDQUFDLENBQUE7UUFFRix5RUFBeUU7UUFDekUsSUFBSSxHQUFHLEtBQUssSUFBSSxJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssUUFBUSxJQUFJLEdBQUcsS0FBSyxTQUFTLENBQUMsRUFBRSxDQUFDO1lBQ25FLE1BQU0sSUFBSSxLQUFLLENBQUMsK0NBQStDLENBQUMsQ0FBQTtRQUNsRSxDQUFDO1FBRUQsNENBQTRDO1FBQzVDLE9BQU8sQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFpQyxDQUFBO0lBQ3BELENBQUM7SUFFRCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsU0FBUyxJQUFJLFVBQVUsQ0FBQyxLQUFLLENBQUE7SUFDdkQsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2YsTUFBTSxJQUFJLEtBQUssQ0FDYiw0RUFBNEUsQ0FDN0UsQ0FBQTtJQUNILENBQUM7SUFFRCxNQUFNLEdBQUcsR0FBRyxHQUFHLElBQUEsOEJBQWdCLEVBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLFFBQVEsRUFBRSxDQUFBO0lBQzdELE1BQU0sT0FBTyxHQUFHLElBQUEsMEJBQVksRUFBQyxPQUFPLENBQUMsQ0FBQTtJQUVyQyxNQUFNLFFBQVEsR0FBRyxNQUFNLFNBQVMsQ0FBQyxHQUFHLElBQUksUUFBUSxFQUFFO1FBQ2hELE1BQU0sRUFBRSxNQUFNO1FBQ2QsT0FBTztRQUNQLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQztLQUM5QixDQUFDLENBQUE7SUFFRixJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ2pCLE1BQU0sSUFBSSxHQUFHLE1BQU0sUUFBUSxDQUFDLElBQUksRUFBRSxDQUFBO1FBQ2xDLE1BQU0sSUFBSSxLQUFLLENBQ2IsSUFBSSxJQUFJLDRDQUE0QyxRQUFRLENBQUMsTUFBTSxHQUFHLENBQ3ZFLENBQUE7SUFDSCxDQUFDO0lBRUQsOERBQThEO0lBQzlELE1BQU0sV0FBVyxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxDQUFBO0lBQ3hELElBQUksV0FBVyxJQUFJLFdBQVcsQ0FBQyxRQUFRLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUFDO1FBQzVELE1BQU0sSUFBSSxHQUFHLE1BQU0sUUFBUSxDQUFDLElBQUksRUFBRSxDQUFBO1FBQ2xDLDJDQUEyQztRQUMzQyxPQUFPLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBaUMsQ0FBQTtJQUNyRCxDQUFDO0lBRUQscUNBQXFDO0lBQ3JDLE9BQU8sRUFBa0MsQ0FBQTtBQUMzQyxDQUFDLENBQUE7QUE1RFksUUFBQSxvQkFBb0Isd0JBNERoQztBQTJDRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EyREc7QUFDSSxNQUFNLHFCQUFxQixHQUFHLEtBQUssRUFDeEMsS0FBaUMsRUFDakMsVUFBd0MsRUFBRSxFQUNGLEVBQUU7SUFDMUMsTUFBTSxRQUFRLEdBQUcsZUFBZSxDQUFDLGdDQUFnQyxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQTtJQUNsRixNQUFNLE9BQU8sR0FBRztRQUNkLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFDLElBQUksRUFBRTtRQUN2QyxRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVE7UUFDeEIsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLO0tBQ25CLENBQUE7SUFFRCxNQUFNLGFBQWEsR0FBRyxJQUFBLDhCQUFnQixFQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUN0RCxJQUFJLGFBQWEsRUFBRSxDQUFDO1FBQ2xCLE1BQU0sT0FBTyxHQUFHLElBQUEsMEJBQVksRUFBQyxPQUFPLENBQUMsQ0FBQTtRQUNyQywyRUFBMkU7UUFDM0UsSUFBSSxLQUFLLENBQUMsS0FBSyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQzFDLE9BQU8sQ0FBQyxhQUFhLEdBQUcsVUFBVSxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUE7UUFDakQsQ0FBQztRQUVELE1BQU0sR0FBRyxHQUFHLE1BQU0sYUFBYSxDQUFDLFFBQVEsRUFBRTtZQUN4QyxNQUFNLEVBQUUsTUFBTTtZQUNkLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQztZQUM3QixPQUFPO1NBQ1IsQ0FBQyxDQUFBO1FBRUYsSUFBSSxDQUFDLEdBQUcsSUFBSSxPQUFPLEdBQUcsS0FBSyxRQUFRLElBQUksQ0FBQyxDQUFDLFNBQVMsSUFBSSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzNELE1BQU0sSUFBSSxLQUFLLENBQUMsMERBQTBELENBQUMsQ0FBQTtRQUM3RSxDQUFDO1FBRUQsT0FBTyxHQUFvQyxDQUFBO0lBQzdDLENBQUM7SUFFRCxNQUFNLFNBQVMsR0FBRyxPQUFPLENBQUMsU0FBUyxJQUFJLFVBQVUsQ0FBQyxLQUFLLENBQUE7SUFDdkQsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2YsTUFBTSxJQUFJLEtBQUssQ0FDYiw0RUFBNEUsQ0FDN0UsQ0FBQTtJQUNILENBQUM7SUFFRCxNQUFNLEdBQUcsR0FBRyxHQUFHLElBQUEsOEJBQWdCLEVBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxHQUFHLFFBQVEsRUFBRSxDQUFBO0lBQzdELE1BQU0sT0FBTyxHQUFHLElBQUEsMEJBQVksRUFBQyxPQUFPLENBQUMsQ0FBQTtJQUNyQywyRUFBMkU7SUFDM0UsSUFBSSxLQUFLLENBQUMsS0FBSyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQzFDLE9BQU8sQ0FBQyxhQUFhLEdBQUcsVUFBVSxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUE7SUFDakQsQ0FBQztJQUVELE1BQU0sUUFBUSxHQUFHLE1BQU0sU0FBUyxDQUFDLEdBQUcsSUFBSSxRQUFRLEVBQUU7UUFDaEQsTUFBTSxFQUFFLE1BQU07UUFDZCxPQUFPO1FBQ1AsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDO0tBQzlCLENBQUMsQ0FBQTtJQUVGLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBRSxFQUFFLENBQUM7UUFDakIsTUFBTSxJQUFJLEdBQUcsTUFBTSxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUE7UUFDbEMsTUFBTSxJQUFJLEtBQUssQ0FDYixJQUFJLElBQUksNkNBQTZDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FDeEUsQ0FBQTtJQUNILENBQUM7SUFFRCxNQUFNLElBQUksR0FBRyxNQUFNLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQTtJQUNsQyxJQUFJLENBQUMsSUFBSSxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsSUFBSSxDQUFDLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxFQUFFLENBQUM7UUFDOUQsTUFBTSxJQUFJLEtBQUssQ0FBQyxpRUFBaUUsQ0FBQyxDQUFBO0lBQ3BGLENBQUM7SUFFRCxPQUFPLElBQXFDLENBQUE7QUFDOUMsQ0FBQyxDQUFBO0FBakVZLFFBQUEscUJBQXFCLHlCQWlFakM7QUFFRDs7R0FFRztBQUNJLE1BQU0sMEJBQTBCLEdBQ3JDLENBQUMsVUFBdUMsRUFBRSxFQUFFLEVBQUUsQ0FDOUMsQ0FBQyxLQUFnQyxFQUFFLEVBQUUsQ0FDbkMsSUFBQSw0QkFBb0IsRUFBQyxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUE7QUFIM0IsUUFBQSwwQkFBMEIsOEJBR0M7QUFFeEM7O0dBRUc7QUFDSSxNQUFNLDJCQUEyQixHQUN0QyxDQUFDLFVBQXdDLEVBQUUsRUFBRSxFQUFFLENBQy9DLENBQUMsS0FBaUMsRUFBRSxFQUFFLENBQ3BDLElBQUEsNkJBQXFCLEVBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxDQUFBO0FBSDVCLFFBQUEsMkJBQTJCLCtCQUdDIn0=