@scalemule/nextjs 0.1.17 → 0.1.19
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/README.md +3 -1
- package/dist/client.d.mts +13 -1
- package/dist/client.d.ts +13 -1
- package/dist/client.js +32 -0
- package/dist/client.mjs +32 -0
- package/dist/index.d.mts +16 -2
- package/dist/index.d.ts +16 -2
- package/dist/index.js +94 -3
- package/dist/index.mjs +94 -4
- package/dist/server/auth.js +130 -21
- package/dist/server/auth.mjs +130 -21
- package/dist/server/index.d.mts +2 -2
- package/dist/server/index.d.ts +2 -2
- package/dist/server/index.js +808 -658
- package/dist/server/index.mjs +809 -659
- package/dist/server/webhook-handler.d.mts +1 -1
- package/dist/server/webhook-handler.d.ts +1 -1
- package/package.json +2 -2
- package/dist/index-DTWyUcyd.d.mts +0 -919
- package/dist/index-DTWyUcyd.d.ts +0 -919
- package/dist/ledvery-CxPzZpxP.d.mts +0 -44
- package/dist/ledvery-CxPzZpxP.d.ts +0 -44
- package/dist/server/ledvery.d.mts +0 -1
- package/dist/server/ledvery.d.ts +0 -1
- package/dist/server/ledvery.js +0 -336
- package/dist/server/ledvery.mjs +0 -333
- package/dist/webhook-handler-C07AK4QB.d.ts +0 -782
- package/dist/webhook-handler-CUp_A0_p.d.mts +0 -782
package/dist/server/auth.js
CHANGED
|
@@ -132,23 +132,31 @@ var ScaleMuleServer = class {
|
|
|
132
132
|
/**
|
|
133
133
|
* Logout user
|
|
134
134
|
*/
|
|
135
|
-
logout: async (sessionToken) => {
|
|
135
|
+
logout: async (sessionToken, options) => {
|
|
136
136
|
return this.request("POST", "/v1/auth/logout", {
|
|
137
|
-
|
|
137
|
+
sessionToken,
|
|
138
|
+
body: { session_token: sessionToken },
|
|
139
|
+
onTokenRotated: options?.onTokenRotated
|
|
138
140
|
});
|
|
139
141
|
},
|
|
140
142
|
/**
|
|
141
143
|
* Get current user from session token
|
|
142
144
|
*/
|
|
143
|
-
me: async (sessionToken) => {
|
|
144
|
-
return this.request("GET", "/v1/auth/me", {
|
|
145
|
+
me: async (sessionToken, options) => {
|
|
146
|
+
return this.request("GET", "/v1/auth/me", {
|
|
147
|
+
sessionToken,
|
|
148
|
+
onTokenRotated: options?.onTokenRotated
|
|
149
|
+
});
|
|
145
150
|
},
|
|
146
151
|
/**
|
|
147
152
|
* Refresh session token
|
|
148
153
|
*/
|
|
149
|
-
refresh: async (sessionToken) => {
|
|
154
|
+
refresh: async (sessionToken, options) => {
|
|
150
155
|
return this.request("POST", "/v1/auth/refresh", {
|
|
151
|
-
|
|
156
|
+
sessionToken,
|
|
157
|
+
clientContext: options?.clientContext,
|
|
158
|
+
isAutoRefresh: options?.isAutoRefresh,
|
|
159
|
+
onTokenRotated: options?.onTokenRotated
|
|
152
160
|
});
|
|
153
161
|
},
|
|
154
162
|
/**
|
|
@@ -180,7 +188,8 @@ var ScaleMuleServer = class {
|
|
|
180
188
|
if (options?.email) {
|
|
181
189
|
return this.request("POST", "/v1/auth/resend-verification", {
|
|
182
190
|
sessionToken: sessionTokenOrEmail,
|
|
183
|
-
body: { email: options.email }
|
|
191
|
+
body: { email: options.email },
|
|
192
|
+
onTokenRotated: options?.onTokenRotated
|
|
184
193
|
});
|
|
185
194
|
}
|
|
186
195
|
if (sessionTokenOrEmail.includes("@")) {
|
|
@@ -189,7 +198,8 @@ var ScaleMuleServer = class {
|
|
|
189
198
|
});
|
|
190
199
|
}
|
|
191
200
|
return this.request("POST", "/v1/auth/resend-verification", {
|
|
192
|
-
sessionToken: sessionTokenOrEmail
|
|
201
|
+
sessionToken: sessionTokenOrEmail,
|
|
202
|
+
onTokenRotated: options?.onTokenRotated
|
|
193
203
|
});
|
|
194
204
|
}
|
|
195
205
|
};
|
|
@@ -200,37 +210,41 @@ var ScaleMuleServer = class {
|
|
|
200
210
|
/**
|
|
201
211
|
* Update user profile
|
|
202
212
|
*/
|
|
203
|
-
update: async (sessionToken, data) => {
|
|
213
|
+
update: async (sessionToken, data, options) => {
|
|
204
214
|
return this.request("PATCH", "/v1/auth/profile", {
|
|
205
215
|
sessionToken,
|
|
206
|
-
body: data
|
|
216
|
+
body: data,
|
|
217
|
+
onTokenRotated: options?.onTokenRotated
|
|
207
218
|
});
|
|
208
219
|
},
|
|
209
220
|
/**
|
|
210
221
|
* Change password
|
|
211
222
|
*/
|
|
212
|
-
changePassword: async (sessionToken, currentPassword, newPassword) => {
|
|
223
|
+
changePassword: async (sessionToken, currentPassword, newPassword, options) => {
|
|
213
224
|
return this.request("POST", "/v1/auth/change-password", {
|
|
214
225
|
sessionToken,
|
|
215
|
-
body: { current_password: currentPassword, new_password: newPassword }
|
|
226
|
+
body: { current_password: currentPassword, new_password: newPassword },
|
|
227
|
+
onTokenRotated: options?.onTokenRotated
|
|
216
228
|
});
|
|
217
229
|
},
|
|
218
230
|
/**
|
|
219
231
|
* Change email
|
|
220
232
|
*/
|
|
221
|
-
changeEmail: async (sessionToken, newEmail, password) => {
|
|
233
|
+
changeEmail: async (sessionToken, newEmail, password, options) => {
|
|
222
234
|
return this.request("POST", "/v1/auth/change-email", {
|
|
223
235
|
sessionToken,
|
|
224
|
-
body: { new_email: newEmail, password }
|
|
236
|
+
body: { new_email: newEmail, password },
|
|
237
|
+
onTokenRotated: options?.onTokenRotated
|
|
225
238
|
});
|
|
226
239
|
},
|
|
227
240
|
/**
|
|
228
241
|
* Delete account
|
|
229
242
|
*/
|
|
230
|
-
deleteAccount: async (sessionToken, password) => {
|
|
243
|
+
deleteAccount: async (sessionToken, password, options) => {
|
|
231
244
|
return this.request("DELETE", "/v1/auth/me", {
|
|
232
245
|
sessionToken,
|
|
233
|
-
body: { password }
|
|
246
|
+
body: { password },
|
|
247
|
+
onTokenRotated: options?.onTokenRotated
|
|
234
248
|
});
|
|
235
249
|
}
|
|
236
250
|
};
|
|
@@ -691,6 +705,9 @@ var ScaleMuleServer = class {
|
|
|
691
705
|
this.apiKey = config.apiKey;
|
|
692
706
|
this.gatewayUrl = resolveGatewayUrl(config);
|
|
693
707
|
this.debug = config.debug || false;
|
|
708
|
+
this.onRefreshStart = config.onRefreshStart;
|
|
709
|
+
this.onRefreshEnd = config.onRefreshEnd;
|
|
710
|
+
this.onAutoRefreshFailed = config.onAutoRefreshFailed;
|
|
694
711
|
this.money = money.createMoneyClient({
|
|
695
712
|
apiKey: this.apiKey,
|
|
696
713
|
gatewayUrl: this.gatewayUrl,
|
|
@@ -734,6 +751,10 @@ var ScaleMuleServer = class {
|
|
|
734
751
|
headers,
|
|
735
752
|
body: options.body ? JSON.stringify(options.body) : void 0
|
|
736
753
|
});
|
|
754
|
+
const rotated = response.headers.get("x-rotated-session-token");
|
|
755
|
+
if (rotated && options.onTokenRotated) {
|
|
756
|
+
options.onTokenRotated(rotated);
|
|
757
|
+
}
|
|
737
758
|
const text = await response.text();
|
|
738
759
|
let responseData = null;
|
|
739
760
|
try {
|
|
@@ -745,6 +766,33 @@ var ScaleMuleServer = class {
|
|
|
745
766
|
code: `HTTP_${response.status}`,
|
|
746
767
|
message: responseData?.message || text || response.statusText
|
|
747
768
|
};
|
|
769
|
+
if (response.status === 401 && options.sessionToken && !options.isAutoRefresh) {
|
|
770
|
+
if (this.debug) console.log("[ScaleMule Server] 401 received, attempting auto-refresh...");
|
|
771
|
+
try {
|
|
772
|
+
this.onRefreshStart?.();
|
|
773
|
+
const refreshData = await this.auth.refresh(options.sessionToken, {
|
|
774
|
+
clientContext: options.clientContext,
|
|
775
|
+
isAutoRefresh: true
|
|
776
|
+
// Prevent infinite loops
|
|
777
|
+
});
|
|
778
|
+
const newToken = refreshData.session_token;
|
|
779
|
+
if (this.debug) console.log("[ScaleMule Server] Auto-refresh succeeded, retrying original request...");
|
|
780
|
+
options.onTokenRotated?.(newToken);
|
|
781
|
+
return this.request(method, path, {
|
|
782
|
+
...options,
|
|
783
|
+
sessionToken: newToken,
|
|
784
|
+
isAutoRefresh: true
|
|
785
|
+
// Don't refresh again on this retry
|
|
786
|
+
});
|
|
787
|
+
} catch (refreshErr) {
|
|
788
|
+
if (this.debug) console.error("[ScaleMule Server] Auto-refresh failed:", refreshErr);
|
|
789
|
+
const refreshApiError = refreshErr instanceof ScaleMuleApiError ? { code: refreshErr.code, message: refreshErr.message } : { code: "REFRESH_FAILED", message: "Auto-refresh failed" };
|
|
790
|
+
this.onAutoRefreshFailed?.(refreshApiError);
|
|
791
|
+
throw new ScaleMuleApiError(error);
|
|
792
|
+
} finally {
|
|
793
|
+
this.onRefreshEnd?.();
|
|
794
|
+
}
|
|
795
|
+
}
|
|
748
796
|
throw new ScaleMuleApiError(error);
|
|
749
797
|
}
|
|
750
798
|
const data = responseData?.data !== void 0 ? responseData.data : responseData;
|
|
@@ -1173,8 +1221,16 @@ function createAuthRoutes(config = {}) {
|
|
|
1173
1221
|
// ==================== Logout ====================
|
|
1174
1222
|
case "logout": {
|
|
1175
1223
|
const session = await getSession();
|
|
1224
|
+
let rotated = null;
|
|
1176
1225
|
if (session) {
|
|
1177
|
-
|
|
1226
|
+
try {
|
|
1227
|
+
await sm.auth.logout(session.sessionToken, {
|
|
1228
|
+
onTokenRotated: (newToken) => {
|
|
1229
|
+
rotated = newToken;
|
|
1230
|
+
}
|
|
1231
|
+
});
|
|
1232
|
+
} catch {
|
|
1233
|
+
}
|
|
1178
1234
|
}
|
|
1179
1235
|
if (config.onLogout) {
|
|
1180
1236
|
await config.onLogout();
|
|
@@ -1239,6 +1295,7 @@ function createAuthRoutes(config = {}) {
|
|
|
1239
1295
|
case "resend-verification": {
|
|
1240
1296
|
const { email } = body;
|
|
1241
1297
|
const session = await getSession();
|
|
1298
|
+
let rotated = null;
|
|
1242
1299
|
if (email) {
|
|
1243
1300
|
try {
|
|
1244
1301
|
await sm.auth.resendVerification(email);
|
|
@@ -1256,7 +1313,11 @@ function createAuthRoutes(config = {}) {
|
|
|
1256
1313
|
return errorResponse("UNAUTHORIZED", "Email or session required", 401);
|
|
1257
1314
|
}
|
|
1258
1315
|
try {
|
|
1259
|
-
await sm.auth.resendVerification(session.sessionToken
|
|
1316
|
+
await sm.auth.resendVerification(session.sessionToken, {
|
|
1317
|
+
onTokenRotated: (newToken) => {
|
|
1318
|
+
rotated = newToken;
|
|
1319
|
+
}
|
|
1320
|
+
});
|
|
1260
1321
|
} catch (err) {
|
|
1261
1322
|
const apiErr = err instanceof ScaleMuleApiError ? err : null;
|
|
1262
1323
|
return errorResponse(
|
|
@@ -1265,6 +1326,14 @@ function createAuthRoutes(config = {}) {
|
|
|
1265
1326
|
400
|
|
1266
1327
|
);
|
|
1267
1328
|
}
|
|
1329
|
+
if (rotated) {
|
|
1330
|
+
return withRefreshedSession(
|
|
1331
|
+
rotated,
|
|
1332
|
+
session.userId,
|
|
1333
|
+
{ success: true, data: { message: "Verification email sent" } },
|
|
1334
|
+
cookieOptions
|
|
1335
|
+
);
|
|
1336
|
+
}
|
|
1268
1337
|
return successResponse({ message: "Verification email sent" });
|
|
1269
1338
|
}
|
|
1270
1339
|
// ==================== Refresh Session ====================
|
|
@@ -1299,11 +1368,17 @@ function createAuthRoutes(config = {}) {
|
|
|
1299
1368
|
if (!current_password || !new_password) {
|
|
1300
1369
|
return errorResponse("VALIDATION_ERROR", "Current and new password required", 400);
|
|
1301
1370
|
}
|
|
1371
|
+
let rotated = null;
|
|
1302
1372
|
try {
|
|
1303
1373
|
await sm.user.changePassword(
|
|
1304
1374
|
session.sessionToken,
|
|
1305
1375
|
current_password,
|
|
1306
|
-
new_password
|
|
1376
|
+
new_password,
|
|
1377
|
+
{
|
|
1378
|
+
onTokenRotated: (newToken) => {
|
|
1379
|
+
rotated = newToken;
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1307
1382
|
);
|
|
1308
1383
|
} catch (err) {
|
|
1309
1384
|
const apiErr = err instanceof ScaleMuleApiError ? err : null;
|
|
@@ -1313,6 +1388,14 @@ function createAuthRoutes(config = {}) {
|
|
|
1313
1388
|
400
|
|
1314
1389
|
);
|
|
1315
1390
|
}
|
|
1391
|
+
if (rotated) {
|
|
1392
|
+
return withRefreshedSession(
|
|
1393
|
+
rotated,
|
|
1394
|
+
session.userId,
|
|
1395
|
+
{ success: true, data: { message: "Password changed successfully" } },
|
|
1396
|
+
cookieOptions
|
|
1397
|
+
);
|
|
1398
|
+
}
|
|
1316
1399
|
return successResponse({ message: "Password changed successfully" });
|
|
1317
1400
|
}
|
|
1318
1401
|
// ==================== Switch Account ====================
|
|
@@ -1393,14 +1476,27 @@ function createAuthRoutes(config = {}) {
|
|
|
1393
1476
|
return withNorm(errorResponse("UNAUTHORIZED", "Authentication required", 401));
|
|
1394
1477
|
}
|
|
1395
1478
|
let userData;
|
|
1479
|
+
let rotated = null;
|
|
1396
1480
|
try {
|
|
1397
|
-
userData = await sm.auth.me(session.sessionToken
|
|
1481
|
+
userData = await sm.auth.me(session.sessionToken, {
|
|
1482
|
+
onTokenRotated: (newToken) => {
|
|
1483
|
+
rotated = newToken;
|
|
1484
|
+
}
|
|
1485
|
+
});
|
|
1398
1486
|
} catch {
|
|
1399
1487
|
return withNorm(clearSession(
|
|
1400
1488
|
{ error: { code: "SESSION_EXPIRED", message: "Session expired" } },
|
|
1401
1489
|
cookieOptions
|
|
1402
1490
|
));
|
|
1403
1491
|
}
|
|
1492
|
+
if (rotated) {
|
|
1493
|
+
return withNorm(withRefreshedSession(
|
|
1494
|
+
rotated,
|
|
1495
|
+
session.userId,
|
|
1496
|
+
{ user: userData, sessionToken: rotated, userId: session.userId },
|
|
1497
|
+
cookieOptions
|
|
1498
|
+
));
|
|
1499
|
+
}
|
|
1404
1500
|
return withNorm(successResponse({ user: userData, sessionToken: session.sessionToken, userId: session.userId }));
|
|
1405
1501
|
}
|
|
1406
1502
|
// ==================== Get Session Status ====================
|
|
@@ -1479,8 +1575,13 @@ function createAuthRoutes(config = {}) {
|
|
|
1479
1575
|
const body = await request.json().catch(() => ({}));
|
|
1480
1576
|
const { full_name, avatar_url } = body;
|
|
1481
1577
|
let updatedUser;
|
|
1578
|
+
let rotated = null;
|
|
1482
1579
|
try {
|
|
1483
|
-
updatedUser = await sm.user.update(session.sessionToken, { full_name, avatar_url }
|
|
1580
|
+
updatedUser = await sm.user.update(session.sessionToken, { full_name, avatar_url }, {
|
|
1581
|
+
onTokenRotated: (newToken) => {
|
|
1582
|
+
rotated = newToken;
|
|
1583
|
+
}
|
|
1584
|
+
});
|
|
1484
1585
|
} catch (err) {
|
|
1485
1586
|
const apiErr = err instanceof ScaleMuleApiError ? err : null;
|
|
1486
1587
|
return errorResponse(
|
|
@@ -1489,6 +1590,14 @@ function createAuthRoutes(config = {}) {
|
|
|
1489
1590
|
400
|
|
1490
1591
|
);
|
|
1491
1592
|
}
|
|
1593
|
+
if (rotated) {
|
|
1594
|
+
return withRefreshedSession(
|
|
1595
|
+
rotated,
|
|
1596
|
+
session.userId,
|
|
1597
|
+
{ success: true, data: { user: updatedUser } },
|
|
1598
|
+
cookieOptions
|
|
1599
|
+
);
|
|
1600
|
+
}
|
|
1492
1601
|
return successResponse({ user: updatedUser });
|
|
1493
1602
|
}
|
|
1494
1603
|
default:
|
package/dist/server/auth.mjs
CHANGED
|
@@ -130,23 +130,31 @@ var ScaleMuleServer = class {
|
|
|
130
130
|
/**
|
|
131
131
|
* Logout user
|
|
132
132
|
*/
|
|
133
|
-
logout: async (sessionToken) => {
|
|
133
|
+
logout: async (sessionToken, options) => {
|
|
134
134
|
return this.request("POST", "/v1/auth/logout", {
|
|
135
|
-
|
|
135
|
+
sessionToken,
|
|
136
|
+
body: { session_token: sessionToken },
|
|
137
|
+
onTokenRotated: options?.onTokenRotated
|
|
136
138
|
});
|
|
137
139
|
},
|
|
138
140
|
/**
|
|
139
141
|
* Get current user from session token
|
|
140
142
|
*/
|
|
141
|
-
me: async (sessionToken) => {
|
|
142
|
-
return this.request("GET", "/v1/auth/me", {
|
|
143
|
+
me: async (sessionToken, options) => {
|
|
144
|
+
return this.request("GET", "/v1/auth/me", {
|
|
145
|
+
sessionToken,
|
|
146
|
+
onTokenRotated: options?.onTokenRotated
|
|
147
|
+
});
|
|
143
148
|
},
|
|
144
149
|
/**
|
|
145
150
|
* Refresh session token
|
|
146
151
|
*/
|
|
147
|
-
refresh: async (sessionToken) => {
|
|
152
|
+
refresh: async (sessionToken, options) => {
|
|
148
153
|
return this.request("POST", "/v1/auth/refresh", {
|
|
149
|
-
|
|
154
|
+
sessionToken,
|
|
155
|
+
clientContext: options?.clientContext,
|
|
156
|
+
isAutoRefresh: options?.isAutoRefresh,
|
|
157
|
+
onTokenRotated: options?.onTokenRotated
|
|
150
158
|
});
|
|
151
159
|
},
|
|
152
160
|
/**
|
|
@@ -178,7 +186,8 @@ var ScaleMuleServer = class {
|
|
|
178
186
|
if (options?.email) {
|
|
179
187
|
return this.request("POST", "/v1/auth/resend-verification", {
|
|
180
188
|
sessionToken: sessionTokenOrEmail,
|
|
181
|
-
body: { email: options.email }
|
|
189
|
+
body: { email: options.email },
|
|
190
|
+
onTokenRotated: options?.onTokenRotated
|
|
182
191
|
});
|
|
183
192
|
}
|
|
184
193
|
if (sessionTokenOrEmail.includes("@")) {
|
|
@@ -187,7 +196,8 @@ var ScaleMuleServer = class {
|
|
|
187
196
|
});
|
|
188
197
|
}
|
|
189
198
|
return this.request("POST", "/v1/auth/resend-verification", {
|
|
190
|
-
sessionToken: sessionTokenOrEmail
|
|
199
|
+
sessionToken: sessionTokenOrEmail,
|
|
200
|
+
onTokenRotated: options?.onTokenRotated
|
|
191
201
|
});
|
|
192
202
|
}
|
|
193
203
|
};
|
|
@@ -198,37 +208,41 @@ var ScaleMuleServer = class {
|
|
|
198
208
|
/**
|
|
199
209
|
* Update user profile
|
|
200
210
|
*/
|
|
201
|
-
update: async (sessionToken, data) => {
|
|
211
|
+
update: async (sessionToken, data, options) => {
|
|
202
212
|
return this.request("PATCH", "/v1/auth/profile", {
|
|
203
213
|
sessionToken,
|
|
204
|
-
body: data
|
|
214
|
+
body: data,
|
|
215
|
+
onTokenRotated: options?.onTokenRotated
|
|
205
216
|
});
|
|
206
217
|
},
|
|
207
218
|
/**
|
|
208
219
|
* Change password
|
|
209
220
|
*/
|
|
210
|
-
changePassword: async (sessionToken, currentPassword, newPassword) => {
|
|
221
|
+
changePassword: async (sessionToken, currentPassword, newPassword, options) => {
|
|
211
222
|
return this.request("POST", "/v1/auth/change-password", {
|
|
212
223
|
sessionToken,
|
|
213
|
-
body: { current_password: currentPassword, new_password: newPassword }
|
|
224
|
+
body: { current_password: currentPassword, new_password: newPassword },
|
|
225
|
+
onTokenRotated: options?.onTokenRotated
|
|
214
226
|
});
|
|
215
227
|
},
|
|
216
228
|
/**
|
|
217
229
|
* Change email
|
|
218
230
|
*/
|
|
219
|
-
changeEmail: async (sessionToken, newEmail, password) => {
|
|
231
|
+
changeEmail: async (sessionToken, newEmail, password, options) => {
|
|
220
232
|
return this.request("POST", "/v1/auth/change-email", {
|
|
221
233
|
sessionToken,
|
|
222
|
-
body: { new_email: newEmail, password }
|
|
234
|
+
body: { new_email: newEmail, password },
|
|
235
|
+
onTokenRotated: options?.onTokenRotated
|
|
223
236
|
});
|
|
224
237
|
},
|
|
225
238
|
/**
|
|
226
239
|
* Delete account
|
|
227
240
|
*/
|
|
228
|
-
deleteAccount: async (sessionToken, password) => {
|
|
241
|
+
deleteAccount: async (sessionToken, password, options) => {
|
|
229
242
|
return this.request("DELETE", "/v1/auth/me", {
|
|
230
243
|
sessionToken,
|
|
231
|
-
body: { password }
|
|
244
|
+
body: { password },
|
|
245
|
+
onTokenRotated: options?.onTokenRotated
|
|
232
246
|
});
|
|
233
247
|
}
|
|
234
248
|
};
|
|
@@ -689,6 +703,9 @@ var ScaleMuleServer = class {
|
|
|
689
703
|
this.apiKey = config.apiKey;
|
|
690
704
|
this.gatewayUrl = resolveGatewayUrl(config);
|
|
691
705
|
this.debug = config.debug || false;
|
|
706
|
+
this.onRefreshStart = config.onRefreshStart;
|
|
707
|
+
this.onRefreshEnd = config.onRefreshEnd;
|
|
708
|
+
this.onAutoRefreshFailed = config.onAutoRefreshFailed;
|
|
692
709
|
this.money = createMoneyClient({
|
|
693
710
|
apiKey: this.apiKey,
|
|
694
711
|
gatewayUrl: this.gatewayUrl,
|
|
@@ -732,6 +749,10 @@ var ScaleMuleServer = class {
|
|
|
732
749
|
headers,
|
|
733
750
|
body: options.body ? JSON.stringify(options.body) : void 0
|
|
734
751
|
});
|
|
752
|
+
const rotated = response.headers.get("x-rotated-session-token");
|
|
753
|
+
if (rotated && options.onTokenRotated) {
|
|
754
|
+
options.onTokenRotated(rotated);
|
|
755
|
+
}
|
|
735
756
|
const text = await response.text();
|
|
736
757
|
let responseData = null;
|
|
737
758
|
try {
|
|
@@ -743,6 +764,33 @@ var ScaleMuleServer = class {
|
|
|
743
764
|
code: `HTTP_${response.status}`,
|
|
744
765
|
message: responseData?.message || text || response.statusText
|
|
745
766
|
};
|
|
767
|
+
if (response.status === 401 && options.sessionToken && !options.isAutoRefresh) {
|
|
768
|
+
if (this.debug) console.log("[ScaleMule Server] 401 received, attempting auto-refresh...");
|
|
769
|
+
try {
|
|
770
|
+
this.onRefreshStart?.();
|
|
771
|
+
const refreshData = await this.auth.refresh(options.sessionToken, {
|
|
772
|
+
clientContext: options.clientContext,
|
|
773
|
+
isAutoRefresh: true
|
|
774
|
+
// Prevent infinite loops
|
|
775
|
+
});
|
|
776
|
+
const newToken = refreshData.session_token;
|
|
777
|
+
if (this.debug) console.log("[ScaleMule Server] Auto-refresh succeeded, retrying original request...");
|
|
778
|
+
options.onTokenRotated?.(newToken);
|
|
779
|
+
return this.request(method, path, {
|
|
780
|
+
...options,
|
|
781
|
+
sessionToken: newToken,
|
|
782
|
+
isAutoRefresh: true
|
|
783
|
+
// Don't refresh again on this retry
|
|
784
|
+
});
|
|
785
|
+
} catch (refreshErr) {
|
|
786
|
+
if (this.debug) console.error("[ScaleMule Server] Auto-refresh failed:", refreshErr);
|
|
787
|
+
const refreshApiError = refreshErr instanceof ScaleMuleApiError ? { code: refreshErr.code, message: refreshErr.message } : { code: "REFRESH_FAILED", message: "Auto-refresh failed" };
|
|
788
|
+
this.onAutoRefreshFailed?.(refreshApiError);
|
|
789
|
+
throw new ScaleMuleApiError(error);
|
|
790
|
+
} finally {
|
|
791
|
+
this.onRefreshEnd?.();
|
|
792
|
+
}
|
|
793
|
+
}
|
|
746
794
|
throw new ScaleMuleApiError(error);
|
|
747
795
|
}
|
|
748
796
|
const data = responseData?.data !== void 0 ? responseData.data : responseData;
|
|
@@ -1171,8 +1219,16 @@ function createAuthRoutes(config = {}) {
|
|
|
1171
1219
|
// ==================== Logout ====================
|
|
1172
1220
|
case "logout": {
|
|
1173
1221
|
const session = await getSession();
|
|
1222
|
+
let rotated = null;
|
|
1174
1223
|
if (session) {
|
|
1175
|
-
|
|
1224
|
+
try {
|
|
1225
|
+
await sm.auth.logout(session.sessionToken, {
|
|
1226
|
+
onTokenRotated: (newToken) => {
|
|
1227
|
+
rotated = newToken;
|
|
1228
|
+
}
|
|
1229
|
+
});
|
|
1230
|
+
} catch {
|
|
1231
|
+
}
|
|
1176
1232
|
}
|
|
1177
1233
|
if (config.onLogout) {
|
|
1178
1234
|
await config.onLogout();
|
|
@@ -1237,6 +1293,7 @@ function createAuthRoutes(config = {}) {
|
|
|
1237
1293
|
case "resend-verification": {
|
|
1238
1294
|
const { email } = body;
|
|
1239
1295
|
const session = await getSession();
|
|
1296
|
+
let rotated = null;
|
|
1240
1297
|
if (email) {
|
|
1241
1298
|
try {
|
|
1242
1299
|
await sm.auth.resendVerification(email);
|
|
@@ -1254,7 +1311,11 @@ function createAuthRoutes(config = {}) {
|
|
|
1254
1311
|
return errorResponse("UNAUTHORIZED", "Email or session required", 401);
|
|
1255
1312
|
}
|
|
1256
1313
|
try {
|
|
1257
|
-
await sm.auth.resendVerification(session.sessionToken
|
|
1314
|
+
await sm.auth.resendVerification(session.sessionToken, {
|
|
1315
|
+
onTokenRotated: (newToken) => {
|
|
1316
|
+
rotated = newToken;
|
|
1317
|
+
}
|
|
1318
|
+
});
|
|
1258
1319
|
} catch (err) {
|
|
1259
1320
|
const apiErr = err instanceof ScaleMuleApiError ? err : null;
|
|
1260
1321
|
return errorResponse(
|
|
@@ -1263,6 +1324,14 @@ function createAuthRoutes(config = {}) {
|
|
|
1263
1324
|
400
|
|
1264
1325
|
);
|
|
1265
1326
|
}
|
|
1327
|
+
if (rotated) {
|
|
1328
|
+
return withRefreshedSession(
|
|
1329
|
+
rotated,
|
|
1330
|
+
session.userId,
|
|
1331
|
+
{ success: true, data: { message: "Verification email sent" } },
|
|
1332
|
+
cookieOptions
|
|
1333
|
+
);
|
|
1334
|
+
}
|
|
1266
1335
|
return successResponse({ message: "Verification email sent" });
|
|
1267
1336
|
}
|
|
1268
1337
|
// ==================== Refresh Session ====================
|
|
@@ -1297,11 +1366,17 @@ function createAuthRoutes(config = {}) {
|
|
|
1297
1366
|
if (!current_password || !new_password) {
|
|
1298
1367
|
return errorResponse("VALIDATION_ERROR", "Current and new password required", 400);
|
|
1299
1368
|
}
|
|
1369
|
+
let rotated = null;
|
|
1300
1370
|
try {
|
|
1301
1371
|
await sm.user.changePassword(
|
|
1302
1372
|
session.sessionToken,
|
|
1303
1373
|
current_password,
|
|
1304
|
-
new_password
|
|
1374
|
+
new_password,
|
|
1375
|
+
{
|
|
1376
|
+
onTokenRotated: (newToken) => {
|
|
1377
|
+
rotated = newToken;
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1305
1380
|
);
|
|
1306
1381
|
} catch (err) {
|
|
1307
1382
|
const apiErr = err instanceof ScaleMuleApiError ? err : null;
|
|
@@ -1311,6 +1386,14 @@ function createAuthRoutes(config = {}) {
|
|
|
1311
1386
|
400
|
|
1312
1387
|
);
|
|
1313
1388
|
}
|
|
1389
|
+
if (rotated) {
|
|
1390
|
+
return withRefreshedSession(
|
|
1391
|
+
rotated,
|
|
1392
|
+
session.userId,
|
|
1393
|
+
{ success: true, data: { message: "Password changed successfully" } },
|
|
1394
|
+
cookieOptions
|
|
1395
|
+
);
|
|
1396
|
+
}
|
|
1314
1397
|
return successResponse({ message: "Password changed successfully" });
|
|
1315
1398
|
}
|
|
1316
1399
|
// ==================== Switch Account ====================
|
|
@@ -1391,14 +1474,27 @@ function createAuthRoutes(config = {}) {
|
|
|
1391
1474
|
return withNorm(errorResponse("UNAUTHORIZED", "Authentication required", 401));
|
|
1392
1475
|
}
|
|
1393
1476
|
let userData;
|
|
1477
|
+
let rotated = null;
|
|
1394
1478
|
try {
|
|
1395
|
-
userData = await sm.auth.me(session.sessionToken
|
|
1479
|
+
userData = await sm.auth.me(session.sessionToken, {
|
|
1480
|
+
onTokenRotated: (newToken) => {
|
|
1481
|
+
rotated = newToken;
|
|
1482
|
+
}
|
|
1483
|
+
});
|
|
1396
1484
|
} catch {
|
|
1397
1485
|
return withNorm(clearSession(
|
|
1398
1486
|
{ error: { code: "SESSION_EXPIRED", message: "Session expired" } },
|
|
1399
1487
|
cookieOptions
|
|
1400
1488
|
));
|
|
1401
1489
|
}
|
|
1490
|
+
if (rotated) {
|
|
1491
|
+
return withNorm(withRefreshedSession(
|
|
1492
|
+
rotated,
|
|
1493
|
+
session.userId,
|
|
1494
|
+
{ user: userData, sessionToken: rotated, userId: session.userId },
|
|
1495
|
+
cookieOptions
|
|
1496
|
+
));
|
|
1497
|
+
}
|
|
1402
1498
|
return withNorm(successResponse({ user: userData, sessionToken: session.sessionToken, userId: session.userId }));
|
|
1403
1499
|
}
|
|
1404
1500
|
// ==================== Get Session Status ====================
|
|
@@ -1477,8 +1573,13 @@ function createAuthRoutes(config = {}) {
|
|
|
1477
1573
|
const body = await request.json().catch(() => ({}));
|
|
1478
1574
|
const { full_name, avatar_url } = body;
|
|
1479
1575
|
let updatedUser;
|
|
1576
|
+
let rotated = null;
|
|
1480
1577
|
try {
|
|
1481
|
-
updatedUser = await sm.user.update(session.sessionToken, { full_name, avatar_url }
|
|
1578
|
+
updatedUser = await sm.user.update(session.sessionToken, { full_name, avatar_url }, {
|
|
1579
|
+
onTokenRotated: (newToken) => {
|
|
1580
|
+
rotated = newToken;
|
|
1581
|
+
}
|
|
1582
|
+
});
|
|
1482
1583
|
} catch (err) {
|
|
1483
1584
|
const apiErr = err instanceof ScaleMuleApiError ? err : null;
|
|
1484
1585
|
return errorResponse(
|
|
@@ -1487,6 +1588,14 @@ function createAuthRoutes(config = {}) {
|
|
|
1487
1588
|
400
|
|
1488
1589
|
);
|
|
1489
1590
|
}
|
|
1591
|
+
if (rotated) {
|
|
1592
|
+
return withRefreshedSession(
|
|
1593
|
+
rotated,
|
|
1594
|
+
session.userId,
|
|
1595
|
+
{ success: true, data: { user: updatedUser } },
|
|
1596
|
+
cookieOptions
|
|
1597
|
+
);
|
|
1598
|
+
}
|
|
1490
1599
|
return successResponse({ user: updatedUser });
|
|
1491
1600
|
}
|
|
1492
1601
|
default:
|
package/dist/server/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as ServerConfig } from '../webhook-handler-
|
|
2
|
-
export { a as ScaleMuleServer, V as VideoFailedEvent, b as VideoReadyEvent, c as VideoTranscodedEvent, d as VideoUploadedEvent, W as WebhookEvent, e as WebhookRoutesConfig, f as createServerClient, g as createWebhookHandler, h as createWebhookRoutes, p as parseWebhookEvent, r as registerVideoWebhook, i as resolveGatewayUrl, v as verifyWebhookSignature } from '../webhook-handler-
|
|
1
|
+
import { S as ServerConfig } from '../webhook-handler-DsxJS_He.mjs';
|
|
2
|
+
export { a as ScaleMuleServer, V as VideoFailedEvent, b as VideoReadyEvent, c as VideoTranscodedEvent, d as VideoUploadedEvent, W as WebhookEvent, e as WebhookRoutesConfig, f as createServerClient, g as createWebhookHandler, h as createWebhookRoutes, p as parseWebhookEvent, r as registerVideoWebhook, i as resolveGatewayUrl, v as verifyWebhookSignature } from '../webhook-handler-DsxJS_He.mjs';
|
|
3
3
|
import { p as ClientContext, A as ApiError } from '../index-DTWyUcyd.mjs';
|
|
4
4
|
export { L as LedveryRoutesConfig, a as LedverySessionData, S as SM_LEDVERY_ACCESS_TOKEN_COOKIE, b as SM_LEDVERY_ID_TOKEN_COOKIE, c as SM_LEDVERY_NONCE_COOKIE, d as SM_LEDVERY_PKCE_VERIFIER_COOKIE, e as SM_LEDVERY_STATE_COOKIE, f as createLedveryRoutes, g as getLedverySession } from '../ledvery-CxPzZpxP.mjs';
|
|
5
5
|
import { NextRequest, NextResponse } from 'next/server';
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as ServerConfig } from '../webhook-handler-
|
|
2
|
-
export { a as ScaleMuleServer, V as VideoFailedEvent, b as VideoReadyEvent, c as VideoTranscodedEvent, d as VideoUploadedEvent, W as WebhookEvent, e as WebhookRoutesConfig, f as createServerClient, g as createWebhookHandler, h as createWebhookRoutes, p as parseWebhookEvent, r as registerVideoWebhook, i as resolveGatewayUrl, v as verifyWebhookSignature } from '../webhook-handler-
|
|
1
|
+
import { S as ServerConfig } from '../webhook-handler-CTx4Uh8u.js';
|
|
2
|
+
export { a as ScaleMuleServer, V as VideoFailedEvent, b as VideoReadyEvent, c as VideoTranscodedEvent, d as VideoUploadedEvent, W as WebhookEvent, e as WebhookRoutesConfig, f as createServerClient, g as createWebhookHandler, h as createWebhookRoutes, p as parseWebhookEvent, r as registerVideoWebhook, i as resolveGatewayUrl, v as verifyWebhookSignature } from '../webhook-handler-CTx4Uh8u.js';
|
|
3
3
|
import { p as ClientContext, A as ApiError } from '../index-DTWyUcyd.js';
|
|
4
4
|
export { L as LedveryRoutesConfig, a as LedverySessionData, S as SM_LEDVERY_ACCESS_TOKEN_COOKIE, b as SM_LEDVERY_ID_TOKEN_COOKIE, c as SM_LEDVERY_NONCE_COOKIE, d as SM_LEDVERY_PKCE_VERIFIER_COOKIE, e as SM_LEDVERY_STATE_COOKIE, f as createLedveryRoutes, g as getLedverySession } from '../ledvery-CxPzZpxP.js';
|
|
5
5
|
import { NextRequest, NextResponse } from 'next/server';
|