@scalemule/nextjs 0.0.37 → 0.0.39

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.
@@ -2745,7 +2745,6 @@ function createServerClient(config) {
2745
2745
  }
2746
2746
  var SESSION_COOKIE_NAME = "sm_session";
2747
2747
  var USER_ID_COOKIE_NAME = "sm_user_id";
2748
- var KNOWN_ACCOUNTS_COOKIE_NAME = "sm_known_accounts";
2749
2748
  ({
2750
2749
  secure: process.env.NODE_ENV === "production"});
2751
2750
  function createCookieHeader(name, value, options = {}) {
@@ -2846,163 +2845,6 @@ function getSessionFromRequest(request) {
2846
2845
  expiresAt: /* @__PURE__ */ new Date()
2847
2846
  };
2848
2847
  }
2849
- var MAX_KNOWN_ACCOUNTS = 10;
2850
- function maskEmail(email) {
2851
- const [local, domain] = email.split("@");
2852
- if (!domain) return "***@***.***";
2853
- const tldDot = domain.lastIndexOf(".");
2854
- const tld = tldDot > 0 ? domain.slice(tldDot) : "";
2855
- const domainBase = tldDot > 0 ? domain.slice(0, tldDot) : domain;
2856
- return `${local[0] || "*"}***@${domainBase[0] || "*"}***${tld}`;
2857
- }
2858
- function stableColorIndex(userId) {
2859
- let hash = 0;
2860
- for (let i = 0; i < userId.length; i++) {
2861
- hash = (hash << 5) - hash + userId.charCodeAt(i) | 0;
2862
- }
2863
- return Math.abs(hash) % 8;
2864
- }
2865
- function applyPrivacyToEntry(entry, privacy) {
2866
- switch (privacy) {
2867
- case "full":
2868
- return entry;
2869
- case "masked":
2870
- return {
2871
- userId: entry.userId,
2872
- email: entry.email ? maskEmail(entry.email) : void 0,
2873
- fullName: entry.fullName ? `${entry.fullName[0].toUpperCase()}.` : void 0,
2874
- provider: entry.provider,
2875
- lastActiveAt: entry.lastActiveAt,
2876
- colorIndex: stableColorIndex(entry.userId)
2877
- };
2878
- case "minimal":
2879
- return {
2880
- userId: entry.userId,
2881
- provider: entry.provider,
2882
- lastActiveAt: entry.lastActiveAt,
2883
- displayLabel: "Account",
2884
- colorIndex: stableColorIndex(entry.userId)
2885
- };
2886
- }
2887
- }
2888
- function appendKnownAccountCookie(headers2, account, existingCookie, options = {}, privacy) {
2889
- let accounts = {};
2890
- if (existingCookie) {
2891
- try {
2892
- accounts = JSON.parse(decodeURIComponent(existingCookie));
2893
- } catch {
2894
- }
2895
- }
2896
- const effectivePrivacy = privacy || "full";
2897
- for (const [userId, entry] of Object.entries(accounts)) {
2898
- accounts[userId] = applyPrivacyToEntry(entry, effectivePrivacy);
2899
- }
2900
- accounts[account.userId] = applyPrivacyToEntry(account, effectivePrivacy);
2901
- const entries = Object.entries(accounts);
2902
- if (entries.length > MAX_KNOWN_ACCOUNTS) {
2903
- entries.sort((a, b) => new Date(b[1].lastActiveAt).getTime() - new Date(a[1].lastActiveAt).getTime());
2904
- accounts = Object.fromEntries(entries.slice(0, MAX_KNOWN_ACCOUNTS));
2905
- }
2906
- const maxAge = 365 * 24 * 60 * 60;
2907
- const secure = options.secure ?? process.env.NODE_ENV === "production";
2908
- const sameSite = options.sameSite ?? "lax";
2909
- const path = options.path ?? "/";
2910
- let cookie = `${KNOWN_ACCOUNTS_COOKIE_NAME}=${encodeURIComponent(JSON.stringify(accounts))}; Path=${path}; Max-Age=${maxAge}; SameSite=${sameSite}`;
2911
- if (secure) {
2912
- cookie += "; Secure";
2913
- }
2914
- if (options.domain) {
2915
- cookie += `; Domain=${options.domain}`;
2916
- }
2917
- headers2.append("Set-Cookie", cookie);
2918
- }
2919
- function removeKnownAccountFromCookie(headers2, userId, existingCookie, options = {}) {
2920
- let accounts = {};
2921
- if (existingCookie) {
2922
- try {
2923
- accounts = JSON.parse(decodeURIComponent(existingCookie));
2924
- } catch {
2925
- }
2926
- }
2927
- delete accounts[userId];
2928
- const maxAge = 365 * 24 * 60 * 60;
2929
- const secure = options.secure ?? process.env.NODE_ENV === "production";
2930
- const sameSite = options.sameSite ?? "lax";
2931
- const path = options.path ?? "/";
2932
- let cookie = `${KNOWN_ACCOUNTS_COOKIE_NAME}=${encodeURIComponent(JSON.stringify(accounts))}; Path=${path}; Max-Age=${maxAge}; SameSite=${sameSite}`;
2933
- if (secure) {
2934
- cookie += "; Secure";
2935
- }
2936
- if (options.domain) {
2937
- cookie += `; Domain=${options.domain}`;
2938
- }
2939
- headers2.append("Set-Cookie", cookie);
2940
- }
2941
- function clearKnownAccountsCookie(headers2, options = {}) {
2942
- const path = options.path ?? "/";
2943
- let cookie = `${KNOWN_ACCOUNTS_COOKIE_NAME}=; Path=${path}; Max-Age=0`;
2944
- if (options.domain) {
2945
- cookie += `; Domain=${options.domain}`;
2946
- }
2947
- headers2.append("Set-Cookie", cookie);
2948
- }
2949
- function getKnownAccountsFromRequest(request) {
2950
- const cookieHeader = request.headers.get("cookie");
2951
- if (!cookieHeader) return [];
2952
- const cookies4 = Object.fromEntries(
2953
- cookieHeader.split(";").map((c) => {
2954
- const [key, ...rest] = c.trim().split("=");
2955
- return [key, decodeURIComponent(rest.join("="))];
2956
- })
2957
- );
2958
- const raw = cookies4[KNOWN_ACCOUNTS_COOKIE_NAME];
2959
- if (!raw) return [];
2960
- try {
2961
- const accounts = JSON.parse(raw);
2962
- return Object.values(accounts);
2963
- } catch {
2964
- return [];
2965
- }
2966
- }
2967
- function getKnownAccountsCookieRaw(request) {
2968
- const cookieHeader = request.headers.get("cookie");
2969
- if (!cookieHeader) return null;
2970
- const cookies4 = Object.fromEntries(
2971
- cookieHeader.split(";").map((c) => {
2972
- const [key, ...rest] = c.trim().split("=");
2973
- return [key, decodeURIComponent(rest.join("="))];
2974
- })
2975
- );
2976
- return cookies4[KNOWN_ACCOUNTS_COOKIE_NAME] || null;
2977
- }
2978
- function normalizeKnownAccountsCookie(request, privacy, options = {}) {
2979
- if (!privacy || privacy === "full") return null;
2980
- const raw = getKnownAccountsCookieRaw(request);
2981
- if (!raw) return null;
2982
- let accounts = {};
2983
- try {
2984
- accounts = JSON.parse(raw);
2985
- } catch {
2986
- return null;
2987
- }
2988
- let changed = false;
2989
- for (const [userId, entry] of Object.entries(accounts)) {
2990
- const normalized = applyPrivacyToEntry(entry, privacy);
2991
- if (JSON.stringify(normalized) !== JSON.stringify(entry)) {
2992
- accounts[userId] = normalized;
2993
- changed = true;
2994
- }
2995
- }
2996
- if (!changed) return null;
2997
- const maxAge = 365 * 24 * 60 * 60;
2998
- const secure = options.secure ?? process.env.NODE_ENV === "production";
2999
- const sameSite = options.sameSite ?? "lax";
3000
- const path = options.path ?? "/";
3001
- let cookie = `${KNOWN_ACCOUNTS_COOKIE_NAME}=${encodeURIComponent(JSON.stringify(accounts))}; Path=${path}; Max-Age=${maxAge}; SameSite=${sameSite}`;
3002
- if (secure) cookie += "; Secure";
3003
- if (options.domain) cookie += `; Domain=${options.domain}`;
3004
- return cookie;
3005
- }
3006
2848
  async function requireSession() {
3007
2849
  const session = await getSession();
3008
2850
  if (!session) {
@@ -3162,25 +3004,7 @@ function createAuthRoutes(config = {}) {
3162
3004
  } catch {
3163
3005
  return successResponse({ user: registeredUser, message: "Registration successful" }, 201);
3164
3006
  }
3165
- const registerResponse = withSession(loginData, { user: registeredUser, sessionToken: loginData.session_token, userId: registeredUser.id }, cookieOptions);
3166
- if (config.enableAccountSwitcher) {
3167
- const existingKnown = getKnownAccountsCookieRaw(request);
3168
- appendKnownAccountCookie(
3169
- registerResponse.headers,
3170
- {
3171
- userId: registeredUser.id,
3172
- email: registeredUser.email,
3173
- fullName: registeredUser.full_name ?? void 0,
3174
- avatarUrl: registeredUser.avatar_url ?? void 0,
3175
- provider: "email",
3176
- lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
3177
- },
3178
- existingKnown,
3179
- cookieOptions,
3180
- config.accountSwitcherPrivacy
3181
- );
3182
- }
3183
- return registerResponse;
3007
+ return withSession(loginData, { user: registeredUser, sessionToken: loginData.session_token, userId: registeredUser.id }, cookieOptions);
3184
3008
  }
3185
3009
  // ==================== Login ====================
3186
3010
  case "login": {
@@ -3211,25 +3035,7 @@ function createAuthRoutes(config = {}) {
3211
3035
  email: loginData.user.email
3212
3036
  });
3213
3037
  }
3214
- const loginResponse = withSession(loginData, { user: loginData.user, sessionToken: loginData.session_token, userId: loginData.user.id }, cookieOptions);
3215
- if (config.enableAccountSwitcher) {
3216
- const existingKnown = getKnownAccountsCookieRaw(request);
3217
- appendKnownAccountCookie(
3218
- loginResponse.headers,
3219
- {
3220
- userId: loginData.user.id,
3221
- email: loginData.user.email,
3222
- fullName: loginData.user.full_name ?? void 0,
3223
- avatarUrl: loginData.user.avatar_url ?? void 0,
3224
- provider: "email",
3225
- lastActiveAt: (/* @__PURE__ */ new Date()).toISOString()
3226
- },
3227
- existingKnown,
3228
- cookieOptions,
3229
- config.accountSwitcherPrivacy
3230
- );
3231
- }
3232
- return loginResponse;
3038
+ return withSession(loginData, { user: loginData.user, sessionToken: loginData.session_token, userId: loginData.user.id }, cookieOptions);
3233
3039
  }
3234
3040
  // ==================== Logout ====================
3235
3041
  case "logout": {
@@ -3376,59 +3182,6 @@ function createAuthRoutes(config = {}) {
3376
3182
  }
3377
3183
  return successResponse({ message: "Password changed successfully" });
3378
3184
  }
3379
- // ==================== Switch Account ====================
3380
- // Clears the active session so the user can re-authenticate as a different account.
3381
- // The known accounts cookie is preserved — only the session cookie is cleared.
3382
- case "switch-account": {
3383
- if (!config.enableAccountSwitcher) {
3384
- return errorResponse("NOT_FOUND", "Account switcher not enabled", 404);
3385
- }
3386
- const session = await getSession();
3387
- if (session) {
3388
- try {
3389
- await sm.auth.logout(session.sessionToken);
3390
- } catch {
3391
- }
3392
- }
3393
- const switchResponse = clearSession({ message: "Session cleared for account switch" }, cookieOptions);
3394
- const knownAccounts = getKnownAccountsFromRequest(request);
3395
- return new Response(
3396
- JSON.stringify({ success: true, data: { message: "Session cleared for account switch", knownAccounts } }),
3397
- { status: 200, headers: switchResponse.headers }
3398
- );
3399
- }
3400
- // ==================== Forget Account ====================
3401
- // Remove a specific account from the known accounts cookie.
3402
- case "forget-account": {
3403
- if (!config.enableAccountSwitcher) {
3404
- return errorResponse("NOT_FOUND", "Account switcher not enabled", 404);
3405
- }
3406
- const { user_id } = body;
3407
- if (!user_id) {
3408
- return errorResponse("VALIDATION_ERROR", "user_id required", 400);
3409
- }
3410
- const headers2 = new Headers();
3411
- headers2.set("Content-Type", "application/json");
3412
- const existingKnown = getKnownAccountsCookieRaw(request);
3413
- removeKnownAccountFromCookie(headers2, user_id, existingKnown, cookieOptions);
3414
- return new Response(
3415
- JSON.stringify({ success: true, data: { message: "Account forgotten" } }),
3416
- { status: 200, headers: headers2 }
3417
- );
3418
- }
3419
- // ==================== Forget All Accounts ====================
3420
- case "forget-all-accounts": {
3421
- if (!config.enableAccountSwitcher) {
3422
- return errorResponse("NOT_FOUND", "Account switcher not enabled", 404);
3423
- }
3424
- const headers2 = new Headers();
3425
- headers2.set("Content-Type", "application/json");
3426
- clearKnownAccountsCookie(headers2, cookieOptions);
3427
- return new Response(
3428
- JSON.stringify({ success: true, data: { message: "All accounts forgotten" } }),
3429
- { status: 200, headers: headers2 }
3430
- );
3431
- }
3432
3185
  default:
3433
3186
  return errorResponse("NOT_FOUND", `Unknown endpoint: ${path}`, 404);
3434
3187
  }
@@ -3444,25 +3197,20 @@ function createAuthRoutes(config = {}) {
3444
3197
  switch (path) {
3445
3198
  // ==================== Get Current User ====================
3446
3199
  case "me": {
3447
- const normCookie = config.enableAccountSwitcher ? normalizeKnownAccountsCookie(request, config.accountSwitcherPrivacy, cookieOptions) : null;
3448
- const withNorm = (resp) => {
3449
- if (normCookie) resp.headers.append("Set-Cookie", normCookie);
3450
- return resp;
3451
- };
3452
3200
  const session = await getSession();
3453
3201
  if (!session) {
3454
- return withNorm(errorResponse("UNAUTHORIZED", "Authentication required", 401));
3202
+ return errorResponse("UNAUTHORIZED", "Authentication required", 401);
3455
3203
  }
3456
3204
  let userData;
3457
3205
  try {
3458
3206
  userData = await sm.auth.me(session.sessionToken);
3459
3207
  } catch {
3460
- return withNorm(clearSession(
3208
+ return clearSession(
3461
3209
  { error: { code: "SESSION_EXPIRED", message: "Session expired" } },
3462
3210
  cookieOptions
3463
- ));
3211
+ );
3464
3212
  }
3465
- return withNorm(successResponse({ user: userData, sessionToken: session.sessionToken, userId: session.userId }));
3213
+ return successResponse({ user: userData, sessionToken: session.sessionToken, userId: session.userId });
3466
3214
  }
3467
3215
  // ==================== Get Session Status ====================
3468
3216
  case "session": {
@@ -3472,14 +3220,6 @@ function createAuthRoutes(config = {}) {
3472
3220
  userId: session?.userId || null
3473
3221
  });
3474
3222
  }
3475
- // ==================== Get Known Accounts ====================
3476
- case "known-accounts": {
3477
- if (!config.enableAccountSwitcher) {
3478
- return errorResponse("NOT_FOUND", "Account switcher not enabled", 404);
3479
- }
3480
- const knownAccounts = getKnownAccountsFromRequest(request);
3481
- return successResponse({ knownAccounts });
3482
- }
3483
3223
  default:
3484
3224
  return errorResponse("NOT_FOUND", `Unknown endpoint: ${path}`, 404);
3485
3225
  }
@@ -5089,17 +4829,14 @@ async function prefetchBundles(keys) {
5089
4829
 
5090
4830
  exports.CSRF_COOKIE_NAME = CSRF_COOKIE_NAME;
5091
4831
  exports.CSRF_HEADER_NAME = CSRF_HEADER_NAME;
5092
- exports.KNOWN_ACCOUNTS_COOKIE_NAME = KNOWN_ACCOUNTS_COOKIE_NAME;
5093
4832
  exports.OAUTH_STATE_COOKIE_NAME = OAUTH_STATE_COOKIE_NAME;
5094
4833
  exports.SESSION_COOKIE_NAME = SESSION_COOKIE_NAME;
5095
4834
  exports.ScaleMuleError = ScaleMuleError;
5096
4835
  exports.ScaleMuleServer = ScaleMuleServer;
5097
4836
  exports.USER_ID_COOKIE_NAME = USER_ID_COOKIE_NAME;
5098
4837
  exports.apiHandler = apiHandler;
5099
- exports.appendKnownAccountCookie = appendKnownAccountCookie;
5100
4838
  exports.buildClientContextHeaders = buildClientContextHeaders;
5101
4839
  exports.buildFlagContext = buildFlagContext;
5102
- exports.clearKnownAccountsCookie = clearKnownAccountsCookie;
5103
4840
  exports.clearOAuthState = clearOAuthState;
5104
4841
  exports.clearSession = clearSession;
5105
4842
  exports.configureBundles = configureBundles;
@@ -5121,8 +4858,6 @@ exports.getAppSecretOrDefault = getAppSecretOrDefault;
5121
4858
  exports.getBootstrapFlags = getBootstrapFlags;
5122
4859
  exports.getBundle = getBundle;
5123
4860
  exports.getCSRFToken = getCSRFToken;
5124
- exports.getKnownAccountsCookieRaw = getKnownAccountsCookieRaw;
5125
- exports.getKnownAccountsFromRequest = getKnownAccountsFromRequest;
5126
4861
  exports.getMySqlBundle = getMySqlBundle;
5127
4862
  exports.getOAuthBundle = getOAuthBundle;
5128
4863
  exports.getPostgresBundle = getPostgresBundle;
@@ -5133,12 +4868,10 @@ exports.getSessionFromRequest = getSessionFromRequest;
5133
4868
  exports.getSmtpBundle = getSmtpBundle;
5134
4869
  exports.invalidateBundleCache = invalidateBundleCache;
5135
4870
  exports.invalidateSecretCache = invalidateSecretCache;
5136
- exports.normalizeKnownAccountsCookie = normalizeKnownAccountsCookie;
5137
4871
  exports.parseWebhookEvent = parseWebhookEvent;
5138
4872
  exports.prefetchBundles = prefetchBundles;
5139
4873
  exports.prefetchSecrets = prefetchSecrets;
5140
4874
  exports.registerVideoWebhook = registerVideoWebhook;
5141
- exports.removeKnownAccountFromCookie = removeKnownAccountFromCookie;
5142
4875
  exports.requireAppSecret = requireAppSecret;
5143
4876
  exports.requireBundle = requireBundle;
5144
4877
  exports.requireSession = requireSession;