@commercengine/storefront-sdk 0.2.1 → 0.3.1
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/index.d.ts +76 -26
- package/dist/index.js +150 -61
- package/dist/lib/auth.d.ts +106 -221
- package/dist/lib/auth.js +223 -680
- package/dist/lib/cart.d.ts +78 -80
- package/dist/lib/cart.js +183 -214
- package/dist/lib/catalog.d.ts +36 -69
- package/dist/lib/catalog.js +109 -118
- package/dist/lib/client.d.ts +38 -43
- package/dist/lib/client.js +88 -145
- package/dist/lib/customer.d.ts +91 -0
- package/dist/lib/customer.js +156 -0
- package/dist/lib/helper.d.ts +28 -0
- package/dist/lib/helper.js +43 -0
- package/dist/lib/jwt-utils.d.ts +75 -0
- package/dist/lib/jwt-utils.js +84 -0
- package/dist/lib/middleware.d.ts +83 -0
- package/dist/lib/middleware.js +257 -0
- package/dist/lib/order.d.ts +73 -0
- package/dist/lib/order.js +128 -0
- package/dist/lib/shipping.d.ts +15 -0
- package/dist/lib/shipping.js +20 -0
- package/dist/types/storefront-api-types.d.ts +359 -0
- package/dist/types/storefront-api-types.js +3 -0
- package/dist/types/storefront.d.ts +7976 -7369
- package/package.json +21 -12
package/dist/lib/auth.js
CHANGED
|
@@ -1,187 +1,42 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.NextCookieTokenStorage = exports.CookieTokenStorage = exports.BrowserTokenStorage = exports.MemoryTokenStorage = exports.AuthClient = void 0;
|
|
4
|
-
exports.createTokenStorage = createTokenStorage;
|
|
5
|
-
const client_1 = require("./client");
|
|
1
|
+
import { StorefrontAPIClient } from "./client";
|
|
6
2
|
/**
|
|
7
3
|
* Client for interacting with authentication endpoints
|
|
8
4
|
*/
|
|
9
|
-
class AuthClient extends
|
|
10
|
-
constructor(config
|
|
5
|
+
export class AuthClient extends StorefrontAPIClient {
|
|
6
|
+
constructor(config) {
|
|
11
7
|
super(config);
|
|
12
|
-
this.autoRefreshTimer = null;
|
|
13
|
-
// Use provided storage or default to memory storage
|
|
14
|
-
this.tokenStorage = tokenStorage || new MemoryTokenStorage();
|
|
15
|
-
// Try to initialize from storage
|
|
16
|
-
const storedToken = this.tokenStorage.getAccessToken();
|
|
17
|
-
if (storedToken) {
|
|
18
|
-
this.setToken(storedToken);
|
|
19
|
-
this.setupAutoRefresh();
|
|
20
|
-
}
|
|
21
8
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
if (this.tokenStorage.getRefreshToken()) {
|
|
28
|
-
this.setupAutoRefresh();
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
// Store refresh token separately
|
|
32
|
-
setRefreshToken(token) {
|
|
33
|
-
this.tokenStorage.setRefreshToken(token);
|
|
34
|
-
}
|
|
35
|
-
// Clear tokens from storage
|
|
36
|
-
clearToken() {
|
|
37
|
-
super.clearToken(); // Assuming this clears the token in the client
|
|
38
|
-
this.tokenStorage.clearTokens();
|
|
39
|
-
this.clearAutoRefresh();
|
|
40
|
-
}
|
|
41
|
-
// Setup auto refresh based on token expiry
|
|
42
|
-
setupAutoRefresh() {
|
|
43
|
-
this.clearAutoRefresh();
|
|
44
|
-
const token = this.tokenStorage.getAccessToken();
|
|
45
|
-
if (!token)
|
|
46
|
-
return;
|
|
47
|
-
const expiryTime = this.getTokenExpiry(token);
|
|
48
|
-
if (!expiryTime)
|
|
49
|
-
return;
|
|
50
|
-
// Calculate refresh time (30 seconds before expiry)
|
|
51
|
-
const currentTime = Math.floor(Date.now() / 1000);
|
|
52
|
-
const timeUntilRefresh = Math.max(0, expiryTime - currentTime - 30) * 1000;
|
|
53
|
-
// Cap the timeout to avoid integer overflow (max 2147483647 ms, ~24.8 days)
|
|
54
|
-
const maxTimeout = 2147483647;
|
|
55
|
-
const safeTimeout = Math.min(timeUntilRefresh, maxTimeout);
|
|
56
|
-
// If the token expires far in the future, we'll need to reset the timer periodically
|
|
57
|
-
if (timeUntilRefresh > maxTimeout) {
|
|
58
|
-
this.autoRefreshTimer = setTimeout(() => {
|
|
59
|
-
this.setupAutoRefresh(); // Recalculate the timer
|
|
60
|
-
}, maxTimeout);
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
this.autoRefreshTimer = setTimeout(() => {
|
|
64
|
-
this.handleTokenRefresh();
|
|
65
|
-
}, safeTimeout);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
clearAutoRefresh() {
|
|
69
|
-
if (this.autoRefreshTimer) {
|
|
70
|
-
clearTimeout(this.autoRefreshTimer);
|
|
71
|
-
this.autoRefreshTimer = null;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
async handleTokenRefresh() {
|
|
75
|
-
try {
|
|
76
|
-
const refreshToken = this.tokenStorage.getRefreshToken();
|
|
77
|
-
if (!refreshToken)
|
|
78
|
-
return;
|
|
79
|
-
const tokens = await this.refreshToken(refreshToken);
|
|
80
|
-
this.setToken(tokens.access_token);
|
|
81
|
-
this.setRefreshToken(tokens.refresh_token);
|
|
82
|
-
}
|
|
83
|
-
catch (error) {
|
|
84
|
-
// If refresh fails, clear tokens
|
|
85
|
-
this.clearToken();
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
getTokenExpiry(token) {
|
|
89
|
-
try {
|
|
90
|
-
// Simple JWT parsing (payload is the middle part between dots)
|
|
91
|
-
const parts = token.split(".");
|
|
92
|
-
if (parts.length !== 3)
|
|
93
|
-
return null;
|
|
94
|
-
// Base64 decode the payload
|
|
95
|
-
// We need to fix the base64 padding for the browser's atob function
|
|
96
|
-
const base64 = parts[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
97
|
-
const padded = base64.padEnd(base64.length + ((4 - (base64.length % 4)) % 4), "=");
|
|
98
|
-
// In Node.js
|
|
99
|
-
let jsonStr;
|
|
100
|
-
if (typeof Buffer !== "undefined") {
|
|
101
|
-
jsonStr = Buffer.from(padded, "base64").toString();
|
|
102
|
-
}
|
|
103
|
-
// In browser
|
|
104
|
-
else if (typeof atob !== "undefined") {
|
|
105
|
-
jsonStr = atob(padded);
|
|
106
|
-
}
|
|
107
|
-
// Fallback
|
|
108
|
-
else {
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
const payload = JSON.parse(jsonStr);
|
|
112
|
-
return payload.exp;
|
|
113
|
-
}
|
|
114
|
-
catch (error) {
|
|
115
|
-
console.error("Error parsing JWT token:", error);
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
9
|
+
/**
|
|
10
|
+
* Get anonymous token for guest users
|
|
11
|
+
*/
|
|
12
|
+
async getAnonymousToken() {
|
|
13
|
+
return this.executeRequest(() => this.client.POST("/auth/anonymous"));
|
|
118
14
|
}
|
|
119
15
|
/**
|
|
120
|
-
*
|
|
16
|
+
* Login with phone number
|
|
121
17
|
*
|
|
122
|
-
* @param
|
|
123
|
-
* @
|
|
18
|
+
* @param phoneNumber - Phone number (without country code)
|
|
19
|
+
* @param countryCode - Country code (defaults to +91)
|
|
20
|
+
* @param registerIfNotExists - Whether to register if user doesn't exist
|
|
21
|
+
* @returns Promise with OTP token and action
|
|
124
22
|
*/
|
|
125
|
-
async
|
|
126
|
-
return this.
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
const hadExistingApiKey = !!this.config.apiKey;
|
|
130
|
-
const originalApiKey = this.config.apiKey;
|
|
131
|
-
try {
|
|
132
|
-
// Set temporary API key if provided
|
|
133
|
-
if (tempApiKey) {
|
|
134
|
-
this.setApiKey(tempApiKey);
|
|
135
|
-
}
|
|
136
|
-
// Check if we have an API key set (either from constructor or from options)
|
|
137
|
-
if (!this.config.apiKey) {
|
|
138
|
-
throw new Error("X-Api-Key is required for anonymous authentication");
|
|
139
|
-
}
|
|
140
|
-
const { data, error } = await this.client.POST("/auth/anonymous");
|
|
141
|
-
if (error) {
|
|
142
|
-
this.handleError(error);
|
|
143
|
-
}
|
|
144
|
-
if (data?.content?.access_token && data?.content?.refresh_token) {
|
|
145
|
-
this.setToken(data.content.access_token);
|
|
146
|
-
this.setRefreshToken(data.content.refresh_token);
|
|
147
|
-
}
|
|
148
|
-
return data?.content;
|
|
149
|
-
}
|
|
150
|
-
finally {
|
|
151
|
-
// Restore the original API key state if we used a temporary one
|
|
152
|
-
if (tempApiKey) {
|
|
153
|
-
if (hadExistingApiKey && originalApiKey) {
|
|
154
|
-
this.setApiKey(originalApiKey);
|
|
155
|
-
}
|
|
156
|
-
else {
|
|
157
|
-
this.clearApiKey();
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
});
|
|
23
|
+
async loginWithPhone(body) {
|
|
24
|
+
return this.executeRequest(() => this.client.POST("/auth/login/phone", {
|
|
25
|
+
body: body,
|
|
26
|
+
}));
|
|
162
27
|
}
|
|
163
28
|
/**
|
|
164
|
-
* Login with
|
|
29
|
+
* Login with WhatsApp
|
|
165
30
|
*
|
|
166
31
|
* @param phoneNumber - Phone number (without country code)
|
|
167
32
|
* @param countryCode - Country code (defaults to +91)
|
|
168
33
|
* @param registerIfNotExists - Whether to register if user doesn't exist
|
|
169
34
|
* @returns Promise with OTP token and action
|
|
170
35
|
*/
|
|
171
|
-
async
|
|
172
|
-
return this.
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
phone: phoneNumber,
|
|
176
|
-
country_code: countryCode,
|
|
177
|
-
register_if_not_exists: registerIfNotExists,
|
|
178
|
-
},
|
|
179
|
-
});
|
|
180
|
-
if (error) {
|
|
181
|
-
this.handleError(error);
|
|
182
|
-
}
|
|
183
|
-
return data?.content;
|
|
184
|
-
});
|
|
36
|
+
async loginWithWhatsApp(body) {
|
|
37
|
+
return this.executeRequest(() => this.client.POST("/auth/login/whatsapp", {
|
|
38
|
+
body: body,
|
|
39
|
+
}));
|
|
185
40
|
}
|
|
186
41
|
/**
|
|
187
42
|
* Login with email
|
|
@@ -190,40 +45,56 @@ class AuthClient extends client_1.StorefrontAPIClient {
|
|
|
190
45
|
* @param registerIfNotExists - Whether to register if user doesn't exist
|
|
191
46
|
* @returns Promise with OTP token and action
|
|
192
47
|
*/
|
|
193
|
-
async loginWithEmail(
|
|
194
|
-
return this.
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
email,
|
|
198
|
-
register_if_not_exists: registerIfNotExists,
|
|
199
|
-
},
|
|
200
|
-
});
|
|
201
|
-
if (error) {
|
|
202
|
-
this.handleError(error);
|
|
203
|
-
}
|
|
204
|
-
return data?.content;
|
|
205
|
-
});
|
|
48
|
+
async loginWithEmail(body) {
|
|
49
|
+
return this.executeRequest(() => this.client.POST("/auth/login/email", {
|
|
50
|
+
body: body,
|
|
51
|
+
}));
|
|
206
52
|
}
|
|
207
53
|
/**
|
|
208
54
|
* Login with password
|
|
209
55
|
*
|
|
210
|
-
* @param
|
|
56
|
+
* @param credentials - Login credentials
|
|
211
57
|
* @returns Promise with user info and tokens
|
|
212
58
|
*/
|
|
213
|
-
async loginWithPassword(
|
|
214
|
-
return this.
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
59
|
+
async loginWithPassword(body) {
|
|
60
|
+
return this.executeRequest(() => this.client.POST("/auth/login/password", {
|
|
61
|
+
body: body,
|
|
62
|
+
}));
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Forgot password
|
|
66
|
+
*
|
|
67
|
+
* @param email - Email address
|
|
68
|
+
* @returns Promise with user info and tokens
|
|
69
|
+
*/
|
|
70
|
+
async forgotPassword(body) {
|
|
71
|
+
return this.executeRequest(() => this.client.POST("/auth/forgot-password", {
|
|
72
|
+
body: body,
|
|
73
|
+
}));
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Reset password
|
|
77
|
+
*
|
|
78
|
+
* @param email - Email address
|
|
79
|
+
* @returns Promise with user info and tokens
|
|
80
|
+
*/
|
|
81
|
+
async resetPassword(body) {
|
|
82
|
+
return this.executeRequest(() => this.client.POST("/auth/reset-password", {
|
|
83
|
+
body: body,
|
|
84
|
+
}));
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Change password
|
|
88
|
+
*
|
|
89
|
+
* @param oldPassword - Old password
|
|
90
|
+
* @param newPassword - New password
|
|
91
|
+
* @param newPasswordConfirmation - New password confirmation
|
|
92
|
+
* @returns Promise with new access token and refresh token
|
|
93
|
+
*/
|
|
94
|
+
async changePassword(body) {
|
|
95
|
+
return this.executeRequest(() => this.client.POST("/auth/change-password", {
|
|
96
|
+
body: body,
|
|
97
|
+
}));
|
|
227
98
|
}
|
|
228
99
|
/**
|
|
229
100
|
* Verify OTP
|
|
@@ -233,24 +104,10 @@ class AuthClient extends client_1.StorefrontAPIClient {
|
|
|
233
104
|
* @param otpAction - OTP action from login request
|
|
234
105
|
* @returns Promise with user info and tokens
|
|
235
106
|
*/
|
|
236
|
-
async verifyOtp(
|
|
237
|
-
return this.
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
otp,
|
|
241
|
-
otp_token: otpToken,
|
|
242
|
-
otp_action: otpAction,
|
|
243
|
-
},
|
|
244
|
-
});
|
|
245
|
-
if (error) {
|
|
246
|
-
this.handleError(error);
|
|
247
|
-
}
|
|
248
|
-
if (data?.content?.access_token && data?.content?.refresh_token) {
|
|
249
|
-
this.setToken(data.content.access_token);
|
|
250
|
-
this.setRefreshToken(data.content.refresh_token);
|
|
251
|
-
}
|
|
252
|
-
return data?.content;
|
|
253
|
-
});
|
|
107
|
+
async verifyOtp(body) {
|
|
108
|
+
return this.executeRequest(() => this.client.POST("/auth/verify-otp", {
|
|
109
|
+
body: body,
|
|
110
|
+
}));
|
|
254
111
|
}
|
|
255
112
|
/**
|
|
256
113
|
* Register with phone
|
|
@@ -258,23 +115,10 @@ class AuthClient extends client_1.StorefrontAPIClient {
|
|
|
258
115
|
* @param options - Registration details
|
|
259
116
|
* @returns Promise with user info and tokens
|
|
260
117
|
*/
|
|
261
|
-
async registerWithPhone(
|
|
262
|
-
return this.
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
...options,
|
|
266
|
-
country_code: options.country_code,
|
|
267
|
-
},
|
|
268
|
-
});
|
|
269
|
-
if (error) {
|
|
270
|
-
this.handleError(error);
|
|
271
|
-
}
|
|
272
|
-
if (data?.content?.access_token && data?.content?.refresh_token) {
|
|
273
|
-
this.setToken(data.content.access_token);
|
|
274
|
-
this.setRefreshToken(data.content.refresh_token);
|
|
275
|
-
}
|
|
276
|
-
return data?.content;
|
|
277
|
-
});
|
|
118
|
+
async registerWithPhone(body) {
|
|
119
|
+
return this.executeRequest(() => this.client.POST("/auth/register/phone", {
|
|
120
|
+
body: body,
|
|
121
|
+
}));
|
|
278
122
|
}
|
|
279
123
|
/**
|
|
280
124
|
* Register with email
|
|
@@ -282,42 +126,20 @@ class AuthClient extends client_1.StorefrontAPIClient {
|
|
|
282
126
|
* @param options - Registration details
|
|
283
127
|
* @returns Promise with user info and tokens
|
|
284
128
|
*/
|
|
285
|
-
async registerWithEmail(
|
|
286
|
-
return this.
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
});
|
|
290
|
-
if (error) {
|
|
291
|
-
this.handleError(error);
|
|
292
|
-
}
|
|
293
|
-
if (data?.content?.access_token && data?.content?.refresh_token) {
|
|
294
|
-
this.setToken(data.content.access_token);
|
|
295
|
-
this.setRefreshToken(data.content.refresh_token);
|
|
296
|
-
}
|
|
297
|
-
return data?.content;
|
|
298
|
-
});
|
|
129
|
+
async registerWithEmail(body) {
|
|
130
|
+
return this.executeRequest(() => this.client.POST("/auth/register/email", {
|
|
131
|
+
body: body,
|
|
132
|
+
}));
|
|
299
133
|
}
|
|
300
134
|
/**
|
|
301
|
-
* Refresh token
|
|
302
|
-
*
|
|
303
|
-
* @
|
|
304
|
-
* @returns Promise with new tokens
|
|
135
|
+
* Refresh the access token using a refresh token
|
|
136
|
+
* @param refreshToken - The refresh token to use for refreshing the access token
|
|
137
|
+
* @returns Promise with the new access token and refresh token
|
|
305
138
|
*/
|
|
306
|
-
async refreshToken(
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
refresh_token: refreshToken,
|
|
311
|
-
},
|
|
312
|
-
});
|
|
313
|
-
if (error) {
|
|
314
|
-
this.handleError(error);
|
|
315
|
-
}
|
|
316
|
-
if (data?.content?.access_token && data?.content?.refresh_token) {
|
|
317
|
-
this.setToken(data.content.access_token);
|
|
318
|
-
this.setRefreshToken(data.content.refresh_token);
|
|
319
|
-
}
|
|
320
|
-
return data?.content;
|
|
139
|
+
async refreshToken(body) {
|
|
140
|
+
return this.executeRequest(() => this.client.POST("/auth/refresh-token", {
|
|
141
|
+
body: body,
|
|
142
|
+
}));
|
|
321
143
|
}
|
|
322
144
|
/**
|
|
323
145
|
* Logout
|
|
@@ -325,460 +147,181 @@ class AuthClient extends client_1.StorefrontAPIClient {
|
|
|
325
147
|
* @returns Promise that resolves when logout is complete
|
|
326
148
|
*/
|
|
327
149
|
async logout() {
|
|
328
|
-
return this.
|
|
329
|
-
const { error } = await this.client.POST("/auth/logout");
|
|
330
|
-
if (error) {
|
|
331
|
-
this.handleError(error);
|
|
332
|
-
}
|
|
333
|
-
this.clearToken();
|
|
334
|
-
});
|
|
150
|
+
return this.executeRequest(() => this.client.POST("/auth/logout"));
|
|
335
151
|
}
|
|
336
152
|
/**
|
|
337
|
-
*
|
|
338
|
-
* to implement token refresh for 401 errors
|
|
153
|
+
* Get user details
|
|
339
154
|
*
|
|
340
|
-
* @
|
|
155
|
+
* @param userId - User ID
|
|
156
|
+
* @returns Promise with user details
|
|
341
157
|
*/
|
|
342
|
-
async
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
if (tokens.access_token) {
|
|
349
|
-
this.setToken(tokens.access_token);
|
|
350
|
-
}
|
|
351
|
-
if (tokens.refresh_token) {
|
|
352
|
-
this.setRefreshToken(tokens.refresh_token);
|
|
353
|
-
}
|
|
354
|
-
return true;
|
|
355
|
-
}
|
|
356
|
-
catch (error) {
|
|
357
|
-
// If refresh fails, clear tokens
|
|
358
|
-
this.clearToken();
|
|
359
|
-
return false;
|
|
360
|
-
}
|
|
158
|
+
async getUserDetails(pathParams) {
|
|
159
|
+
return this.executeRequest(() => this.client.GET("/auth/user/{id}", {
|
|
160
|
+
params: {
|
|
161
|
+
path: pathParams,
|
|
162
|
+
},
|
|
163
|
+
}));
|
|
361
164
|
}
|
|
362
165
|
/**
|
|
363
|
-
*
|
|
364
|
-
* This wraps any API call in logic that will catch authentication errors,
|
|
365
|
-
* attempt to refresh the token, and retry the request once
|
|
166
|
+
* Update user details
|
|
366
167
|
*
|
|
367
|
-
* @param
|
|
368
|
-
* @returns Promise with
|
|
168
|
+
* @param userId - User ID
|
|
169
|
+
* @returns Promise with user details
|
|
369
170
|
*/
|
|
370
|
-
async
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
if (error instanceof Error &&
|
|
378
|
-
error.message === "Token refreshed, please retry the request") {
|
|
379
|
-
return await requestFn();
|
|
380
|
-
}
|
|
381
|
-
// Otherwise, re-throw the error
|
|
382
|
-
throw error;
|
|
383
|
-
}
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
exports.AuthClient = AuthClient;
|
|
387
|
-
/**
|
|
388
|
-
* Default in-memory implementation of client storage
|
|
389
|
-
*/
|
|
390
|
-
class MemoryTokenStorage {
|
|
391
|
-
constructor() {
|
|
392
|
-
this.accessToken = null;
|
|
393
|
-
this.refreshToken = null;
|
|
394
|
-
this.cartId = null;
|
|
395
|
-
}
|
|
396
|
-
getAccessToken() {
|
|
397
|
-
return this.accessToken;
|
|
398
|
-
}
|
|
399
|
-
setAccessToken(token) {
|
|
400
|
-
this.accessToken = token;
|
|
401
|
-
}
|
|
402
|
-
getRefreshToken() {
|
|
403
|
-
return this.refreshToken;
|
|
404
|
-
}
|
|
405
|
-
setRefreshToken(token) {
|
|
406
|
-
this.refreshToken = token;
|
|
407
|
-
}
|
|
408
|
-
clearTokens() {
|
|
409
|
-
this.accessToken = null;
|
|
410
|
-
this.refreshToken = null;
|
|
411
|
-
}
|
|
412
|
-
getCartId() {
|
|
413
|
-
return this.cartId;
|
|
414
|
-
}
|
|
415
|
-
setCartId(cartId) {
|
|
416
|
-
this.cartId = cartId;
|
|
417
|
-
}
|
|
418
|
-
clearCartId() {
|
|
419
|
-
this.cartId = null;
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
exports.MemoryTokenStorage = MemoryTokenStorage;
|
|
423
|
-
/**
|
|
424
|
-
* Browser storage implementation using localStorage
|
|
425
|
-
*/
|
|
426
|
-
class BrowserTokenStorage {
|
|
427
|
-
constructor(prefix = "storefront_") {
|
|
428
|
-
this.accessTokenKey = `${prefix}access_token`;
|
|
429
|
-
this.refreshTokenKey = `${prefix}refresh_token`;
|
|
430
|
-
this.cartIdKey = `${prefix}cart_id`;
|
|
431
|
-
}
|
|
432
|
-
getAccessToken() {
|
|
433
|
-
if (typeof localStorage === "undefined")
|
|
434
|
-
return null;
|
|
435
|
-
return localStorage.getItem(this.accessTokenKey);
|
|
436
|
-
}
|
|
437
|
-
setAccessToken(token) {
|
|
438
|
-
if (typeof localStorage === "undefined")
|
|
439
|
-
return;
|
|
440
|
-
localStorage.setItem(this.accessTokenKey, token);
|
|
441
|
-
}
|
|
442
|
-
getRefreshToken() {
|
|
443
|
-
if (typeof localStorage === "undefined")
|
|
444
|
-
return null;
|
|
445
|
-
return localStorage.getItem(this.refreshTokenKey);
|
|
446
|
-
}
|
|
447
|
-
setRefreshToken(token) {
|
|
448
|
-
if (typeof localStorage === "undefined")
|
|
449
|
-
return;
|
|
450
|
-
localStorage.setItem(this.refreshTokenKey, token);
|
|
451
|
-
}
|
|
452
|
-
clearTokens() {
|
|
453
|
-
if (typeof localStorage === "undefined")
|
|
454
|
-
return;
|
|
455
|
-
localStorage.removeItem(this.accessTokenKey);
|
|
456
|
-
localStorage.removeItem(this.refreshTokenKey);
|
|
457
|
-
}
|
|
458
|
-
getCartId() {
|
|
459
|
-
if (typeof localStorage === "undefined")
|
|
460
|
-
return null;
|
|
461
|
-
return localStorage.getItem(this.cartIdKey);
|
|
462
|
-
}
|
|
463
|
-
setCartId(cartId) {
|
|
464
|
-
if (typeof localStorage === "undefined")
|
|
465
|
-
return;
|
|
466
|
-
localStorage.setItem(this.cartIdKey, cartId);
|
|
467
|
-
}
|
|
468
|
-
clearCartId() {
|
|
469
|
-
if (typeof localStorage === "undefined")
|
|
470
|
-
return;
|
|
471
|
-
localStorage.removeItem(this.cartIdKey);
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
exports.BrowserTokenStorage = BrowserTokenStorage;
|
|
475
|
-
/**
|
|
476
|
-
* Cookie-based token storage for browser or server environments
|
|
477
|
-
*/
|
|
478
|
-
class CookieTokenStorage {
|
|
479
|
-
constructor(prefix = "storefront_", cookieOptions = {
|
|
480
|
-
path: "/",
|
|
481
|
-
secure: true,
|
|
482
|
-
sameSite: "lax",
|
|
483
|
-
httpOnly: true,
|
|
484
|
-
maxAge: 60 * 60 * 24 * 30, // 30 days
|
|
485
|
-
}) {
|
|
486
|
-
this.accessTokenKey = `${prefix}access_token`;
|
|
487
|
-
this.refreshTokenKey = `${prefix}refresh_token`;
|
|
488
|
-
this.cartIdKey = `${prefix}cart_id`;
|
|
489
|
-
this.cookieOptions = cookieOptions;
|
|
490
|
-
}
|
|
491
|
-
/**
|
|
492
|
-
* Get access token from cookies
|
|
493
|
-
* Works in both browser and Next.js server components
|
|
494
|
-
*/
|
|
495
|
-
getAccessToken() {
|
|
496
|
-
// Browser environment
|
|
497
|
-
if (typeof document !== "undefined") {
|
|
498
|
-
return getCookieValue(this.accessTokenKey);
|
|
499
|
-
}
|
|
500
|
-
// Next.js server component - would need to be implemented by user
|
|
501
|
-
// with their specific cookie library
|
|
502
|
-
return null;
|
|
503
|
-
}
|
|
504
|
-
/**
|
|
505
|
-
* Set access token in cookies
|
|
506
|
-
* Works in browser environment
|
|
507
|
-
*/
|
|
508
|
-
setAccessToken(token) {
|
|
509
|
-
// Browser environment
|
|
510
|
-
if (typeof document !== "undefined") {
|
|
511
|
-
setCookie(this.accessTokenKey, token, this.cookieOptions);
|
|
512
|
-
}
|
|
513
|
-
// Next.js - would need to be implemented by user
|
|
514
|
-
// with their specific cookie API
|
|
515
|
-
}
|
|
516
|
-
/**
|
|
517
|
-
* Get refresh token from cookies
|
|
518
|
-
* Works in both browser and Next.js server components
|
|
519
|
-
*/
|
|
520
|
-
getRefreshToken() {
|
|
521
|
-
// Browser environment
|
|
522
|
-
if (typeof document !== "undefined") {
|
|
523
|
-
return getCookieValue(this.refreshTokenKey);
|
|
524
|
-
}
|
|
525
|
-
// Next.js server component - would need to be implemented by user
|
|
526
|
-
return null;
|
|
527
|
-
}
|
|
528
|
-
/**
|
|
529
|
-
* Set refresh token in cookies
|
|
530
|
-
* Works in browser environment
|
|
531
|
-
*/
|
|
532
|
-
setRefreshToken(token) {
|
|
533
|
-
// Browser environment
|
|
534
|
-
if (typeof document !== "undefined") {
|
|
535
|
-
setCookie(this.refreshTokenKey, token, this.cookieOptions);
|
|
536
|
-
}
|
|
537
|
-
// Next.js - would need to be implemented by user
|
|
538
|
-
}
|
|
539
|
-
/**
|
|
540
|
-
* Clear all tokens from cookies
|
|
541
|
-
*/
|
|
542
|
-
clearTokens() {
|
|
543
|
-
// Browser environment
|
|
544
|
-
if (typeof document !== "undefined") {
|
|
545
|
-
deleteCookie(this.accessTokenKey);
|
|
546
|
-
deleteCookie(this.refreshTokenKey);
|
|
547
|
-
}
|
|
548
|
-
// Next.js - would need to be implemented by user
|
|
549
|
-
}
|
|
550
|
-
/**
|
|
551
|
-
* Get cart ID from cookies
|
|
552
|
-
* Works in both browser and Next.js server components
|
|
553
|
-
*/
|
|
554
|
-
getCartId() {
|
|
555
|
-
// Browser environment
|
|
556
|
-
if (typeof document !== "undefined") {
|
|
557
|
-
return getCookieValue(this.cartIdKey);
|
|
558
|
-
}
|
|
559
|
-
// Next.js server component - would need to be implemented by user
|
|
560
|
-
return null;
|
|
171
|
+
async updateUserDetails(pathParams, body) {
|
|
172
|
+
return this.executeRequest(() => this.client.PUT("/auth/user/{id}", {
|
|
173
|
+
params: {
|
|
174
|
+
path: pathParams,
|
|
175
|
+
},
|
|
176
|
+
body: body,
|
|
177
|
+
}));
|
|
561
178
|
}
|
|
562
179
|
/**
|
|
563
|
-
*
|
|
564
|
-
*
|
|
180
|
+
* Add profile image
|
|
181
|
+
*
|
|
182
|
+
* @param userId - User ID
|
|
183
|
+
* @returns Promise with user details
|
|
565
184
|
*/
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
185
|
+
async addProfileImage(pathParams, formData) {
|
|
186
|
+
return this.executeRequest(() => this.client.POST("/auth/user/{id}/profile-image", {
|
|
187
|
+
params: {
|
|
188
|
+
path: pathParams,
|
|
189
|
+
},
|
|
190
|
+
body: formData,
|
|
191
|
+
bodySerializer: (body) => {
|
|
192
|
+
const fd = new FormData();
|
|
193
|
+
for (const [key, value] of Object.entries(body)) {
|
|
194
|
+
if (value !== undefined && value !== null) {
|
|
195
|
+
fd.append(key, value);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return fd;
|
|
199
|
+
}
|
|
200
|
+
}));
|
|
572
201
|
}
|
|
573
202
|
/**
|
|
574
|
-
*
|
|
203
|
+
* Update profile image
|
|
204
|
+
*
|
|
205
|
+
* @param userId - User ID
|
|
206
|
+
* @returns Promise with user details
|
|
575
207
|
*/
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
return match ? decodeURIComponent(match[2]) : null;
|
|
593
|
-
}
|
|
594
|
-
/**
|
|
595
|
-
* Helper function to set cookie
|
|
596
|
-
*/
|
|
597
|
-
function setCookie(name, value, options = {}) {
|
|
598
|
-
if (typeof document === "undefined")
|
|
599
|
-
return;
|
|
600
|
-
const cookieOptions = {
|
|
601
|
-
path: "/",
|
|
602
|
-
...options,
|
|
603
|
-
};
|
|
604
|
-
let cookie = `${name}=${encodeURIComponent(value)}`;
|
|
605
|
-
if (cookieOptions.maxAge) {
|
|
606
|
-
cookie += `; max-age=${cookieOptions.maxAge}`;
|
|
607
|
-
}
|
|
608
|
-
if (cookieOptions.domain) {
|
|
609
|
-
cookie += `; domain=${cookieOptions.domain}`;
|
|
610
|
-
}
|
|
611
|
-
if (cookieOptions.path) {
|
|
612
|
-
cookie += `; path=${cookieOptions.path}`;
|
|
613
|
-
}
|
|
614
|
-
if (cookieOptions.secure) {
|
|
615
|
-
cookie += "; secure";
|
|
616
|
-
}
|
|
617
|
-
if (cookieOptions.sameSite) {
|
|
618
|
-
cookie += `; samesite=${cookieOptions.sameSite}`;
|
|
619
|
-
}
|
|
620
|
-
document.cookie = cookie;
|
|
621
|
-
}
|
|
622
|
-
/**
|
|
623
|
-
* Helper function to delete cookie
|
|
624
|
-
*/
|
|
625
|
-
function deleteCookie(name, path = "/") {
|
|
626
|
-
if (typeof document === "undefined")
|
|
627
|
-
return;
|
|
628
|
-
document.cookie = `${name}=; path=${path}; expires=Thu, 01 Jan 1970 00:00:01 GMT`;
|
|
629
|
-
}
|
|
630
|
-
/**
|
|
631
|
-
* Next.js specific cookie storage implementation
|
|
632
|
-
* Works with the Next.js cookies API
|
|
633
|
-
*/
|
|
634
|
-
class NextCookieTokenStorage {
|
|
635
|
-
constructor(cookieStore, prefix = "storefront_") {
|
|
636
|
-
this.accessTokenKey = `${prefix}access_token`;
|
|
637
|
-
this.refreshTokenKey = `${prefix}refresh_token`;
|
|
638
|
-
this.cartIdKey = `${prefix}cart_id`;
|
|
639
|
-
this.cookieStore = cookieStore;
|
|
208
|
+
async updateProfileImage(pathParams, formData) {
|
|
209
|
+
return this.executeRequest(() => this.client.PUT("/auth/user/{id}/profile-image", {
|
|
210
|
+
params: {
|
|
211
|
+
path: pathParams,
|
|
212
|
+
},
|
|
213
|
+
body: formData,
|
|
214
|
+
bodySerializer: (body) => {
|
|
215
|
+
const fd = new FormData();
|
|
216
|
+
for (const [key, value] of Object.entries(body)) {
|
|
217
|
+
if (value !== undefined && value !== null) {
|
|
218
|
+
fd.append(key, value);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
return fd;
|
|
222
|
+
}
|
|
223
|
+
}));
|
|
640
224
|
}
|
|
641
225
|
/**
|
|
642
|
-
*
|
|
226
|
+
* Delete profile image
|
|
227
|
+
*
|
|
228
|
+
* @param userId - User ID
|
|
229
|
+
* @returns Promise with user details
|
|
643
230
|
*/
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
}
|
|
650
|
-
catch (error) {
|
|
651
|
-
return null;
|
|
652
|
-
}
|
|
231
|
+
async deleteProfileImage(pathParams) {
|
|
232
|
+
return this.executeRequest(() => this.client.DELETE("/auth/user/{id}/profile-image", {
|
|
233
|
+
params: {
|
|
234
|
+
path: pathParams,
|
|
235
|
+
},
|
|
236
|
+
}));
|
|
653
237
|
}
|
|
654
238
|
/**
|
|
655
|
-
*
|
|
239
|
+
* Get profile image
|
|
240
|
+
*
|
|
241
|
+
* @param userId - User ID
|
|
242
|
+
* @returns Promise with user details
|
|
656
243
|
*/
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
httpOnly: true,
|
|
664
|
-
sameSite: "strict",
|
|
665
|
-
maxAge: 60 * 60 * 24 * 30, // 30 days
|
|
666
|
-
});
|
|
667
|
-
}
|
|
668
|
-
catch (error) {
|
|
669
|
-
// Silently fail - might be in an environment where cookies can't be set
|
|
670
|
-
}
|
|
244
|
+
async getProfileImage(pathParams) {
|
|
245
|
+
return this.executeRequest(() => this.client.GET("/auth/user/{id}/profile-image", {
|
|
246
|
+
params: {
|
|
247
|
+
path: pathParams,
|
|
248
|
+
},
|
|
249
|
+
}));
|
|
671
250
|
}
|
|
672
251
|
/**
|
|
673
|
-
*
|
|
252
|
+
* Deactivate user account
|
|
253
|
+
*
|
|
254
|
+
* @param userId - User ID
|
|
255
|
+
* @returns Promise with user details
|
|
674
256
|
*/
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
}
|
|
681
|
-
catch (error) {
|
|
682
|
-
return null;
|
|
683
|
-
}
|
|
257
|
+
async deactivateUserAccount(pathParams) {
|
|
258
|
+
return this.executeRequest(() => this.client.PUT("/auth/user/{id}/deactivate", {
|
|
259
|
+
params: {
|
|
260
|
+
path: pathParams,
|
|
261
|
+
},
|
|
262
|
+
}));
|
|
684
263
|
}
|
|
685
264
|
/**
|
|
686
|
-
*
|
|
265
|
+
* Get user notification preferences
|
|
266
|
+
*
|
|
267
|
+
* @param userId - User ID
|
|
268
|
+
* @returns Promise with user details
|
|
687
269
|
*/
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
httpOnly: true,
|
|
695
|
-
sameSite: "strict",
|
|
696
|
-
maxAge: 60 * 60 * 24 * 30, // 30 days
|
|
697
|
-
});
|
|
698
|
-
}
|
|
699
|
-
catch (error) {
|
|
700
|
-
// Silently fail
|
|
701
|
-
}
|
|
270
|
+
async getUserNotificationPreferences(pathParams) {
|
|
271
|
+
return this.executeRequest(() => this.client.GET("/auth/user/{id}/notification-preferences", {
|
|
272
|
+
params: {
|
|
273
|
+
path: pathParams,
|
|
274
|
+
},
|
|
275
|
+
}));
|
|
702
276
|
}
|
|
703
277
|
/**
|
|
704
|
-
*
|
|
278
|
+
* Update user notification preferences
|
|
279
|
+
*
|
|
280
|
+
* @param userId - User ID
|
|
281
|
+
* @returns Promise with user details
|
|
705
282
|
*/
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
// Silently fail
|
|
714
|
-
}
|
|
283
|
+
async updateUserNotificationPreferences(pathParams, body) {
|
|
284
|
+
return this.executeRequest(() => this.client.PUT("/auth/user/{id}/notification-preferences", {
|
|
285
|
+
params: {
|
|
286
|
+
path: pathParams,
|
|
287
|
+
},
|
|
288
|
+
body: body,
|
|
289
|
+
}));
|
|
715
290
|
}
|
|
716
291
|
/**
|
|
717
|
-
*
|
|
292
|
+
* Create user notification preference
|
|
293
|
+
*
|
|
294
|
+
* @param userId - User ID
|
|
295
|
+
* @returns Promise with user details
|
|
718
296
|
*/
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
return null;
|
|
727
|
-
}
|
|
297
|
+
async createUserNotificationPreference(pathParams, body) {
|
|
298
|
+
return this.executeRequest(() => this.client.POST("/auth/user/{id}/notification-preferences", {
|
|
299
|
+
params: {
|
|
300
|
+
path: pathParams,
|
|
301
|
+
},
|
|
302
|
+
body: body,
|
|
303
|
+
}));
|
|
728
304
|
}
|
|
729
305
|
/**
|
|
730
|
-
*
|
|
306
|
+
* Generate OTP
|
|
307
|
+
*
|
|
308
|
+
* @param body - OTP generation body
|
|
309
|
+
* @returns Promise with OTP generation response
|
|
731
310
|
*/
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
path: "/",
|
|
737
|
-
secure: process.env.NODE_ENV === "production",
|
|
738
|
-
httpOnly: true,
|
|
739
|
-
sameSite: "strict",
|
|
740
|
-
maxAge: 60 * 60 * 24 * 30, // 30 days
|
|
741
|
-
});
|
|
742
|
-
}
|
|
743
|
-
catch (error) {
|
|
744
|
-
// Silently fail
|
|
745
|
-
}
|
|
311
|
+
async generateOtp(body) {
|
|
312
|
+
return this.executeRequest(() => this.client.POST("/auth/generate-otp", {
|
|
313
|
+
body: body,
|
|
314
|
+
}));
|
|
746
315
|
}
|
|
747
316
|
/**
|
|
748
|
-
*
|
|
317
|
+
* Check whether email or phone is already verified
|
|
318
|
+
*
|
|
319
|
+
* @param body - OTP generation body
|
|
320
|
+
* @returns Promise with OTP generation response
|
|
749
321
|
*/
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
}
|
|
755
|
-
catch (error) {
|
|
756
|
-
// Silently fail
|
|
757
|
-
}
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
exports.NextCookieTokenStorage = NextCookieTokenStorage;
|
|
761
|
-
/**
|
|
762
|
-
* Helper to create a token storage instance based on environment
|
|
763
|
-
* Automatically selects the best storage method based on context
|
|
764
|
-
*/
|
|
765
|
-
function createTokenStorage(options) {
|
|
766
|
-
const prefix = options?.prefix || "storefront_";
|
|
767
|
-
// Node.js environment without a cookieStore - use memory
|
|
768
|
-
if (typeof window === "undefined" && !options?.cookieStore) {
|
|
769
|
-
return new MemoryTokenStorage();
|
|
770
|
-
}
|
|
771
|
-
// Next.js server component with cookieStore
|
|
772
|
-
if (typeof window === "undefined" && options?.cookieStore) {
|
|
773
|
-
return new NextCookieTokenStorage(options.cookieStore, prefix);
|
|
774
|
-
}
|
|
775
|
-
// Browser environment - use localStorage by default unless cookies are specified
|
|
776
|
-
if (typeof window !== "undefined") {
|
|
777
|
-
if (options?.useLocalStorage === false) {
|
|
778
|
-
return new CookieTokenStorage(prefix);
|
|
779
|
-
}
|
|
780
|
-
return new BrowserTokenStorage(prefix);
|
|
322
|
+
async checkEmailOrPhoneIsVerified(body) {
|
|
323
|
+
return this.executeRequest(() => this.client.POST("/auth/verified-email-phone", {
|
|
324
|
+
body: body,
|
|
325
|
+
}));
|
|
781
326
|
}
|
|
782
|
-
// Fallback to memory storage
|
|
783
|
-
return new MemoryTokenStorage();
|
|
784
327
|
}
|