@salesforce/webapp-template-app-react-template-vibe-experimental 1.44.0 → 1.45.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.
Files changed (41) hide show
  1. package/dist/CHANGELOG.md +16 -0
  2. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/package-lock.json +1177 -405
  3. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/package.json +2 -4
  4. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/app.tsx +2 -5
  5. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/auth/authHelpers.ts +73 -0
  6. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/{utils → components/auth}/authenticationConfig.ts +9 -0
  7. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/auth/{authentication-route.tsx → authenticationRouteLayout.tsx} +1 -1
  8. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/auth/{private-route.tsx → privateRouteLayout.tsx} +1 -1
  9. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/auth/sessionTimeout/SessionTimeoutValidator.tsx +616 -0
  10. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/auth/sessionTimeout/sessionTimeService.ts +161 -0
  11. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/auth/sessionTimeout/sessionTimeoutConfig.ts +77 -0
  12. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/ui/alert.tsx +17 -13
  13. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/ui/button.tsx +35 -22
  14. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/ui/card.tsx +27 -12
  15. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/ui/dialog.tsx +143 -0
  16. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/ui/field.tsx +157 -46
  17. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/ui/index.ts +1 -0
  18. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/ui/input.tsx +3 -3
  19. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/ui/label.tsx +2 -2
  20. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/ui/pagination.tsx +87 -74
  21. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/ui/select.tsx +156 -124
  22. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/ui/separator.tsx +26 -0
  23. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/ui/skeleton.tsx +1 -0
  24. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/ui/spinner.tsx +5 -16
  25. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/ui/table.tsx +68 -95
  26. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/components/ui/tabs.tsx +47 -84
  27. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/context/AuthContext.tsx +12 -0
  28. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/hooks/form.tsx +1 -1
  29. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/hooks/useCountdownTimer.ts +266 -0
  30. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/hooks/useRetryWithBackoff.ts +109 -0
  31. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/layouts/AuthAppLayout.tsx +12 -0
  32. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/pages/ChangePassword.tsx +3 -2
  33. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/pages/ForgotPassword.tsx +1 -1
  34. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/pages/Login.tsx +3 -3
  35. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/pages/Profile.tsx +3 -2
  36. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/pages/Register.tsx +4 -5
  37. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/pages/ResetPassword.tsx +3 -2
  38. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/routes.tsx +4 -4
  39. package/dist/force-app/main/default/webapplications/appreacttemplatevibe/src/utils/helpers.ts +0 -74
  40. package/dist/package.json +1 -1
  41. package/package.json +2 -2
@@ -14,10 +14,7 @@
14
14
  "graphql:schema": "node scripts/get-graphql-schema.mjs"
15
15
  },
16
16
  "dependencies": {
17
- "@radix-ui/react-label": "^2.1.8",
18
- "@radix-ui/react-select": "^2.2.6",
19
- "@radix-ui/react-slot": "^1.2.4",
20
- "@salesforce/agentforce-conversation-client": "^1.43.1",
17
+ "@salesforce/agentforce-conversation-client": "^1.45.0",
21
18
  "@salesforce/sdk-data": "^1.11.2",
22
19
  "@salesforce/webapp-experimental": "*",
23
20
  "@tailwindcss/vite": "^4.1.17",
@@ -25,6 +22,7 @@
25
22
  "class-variance-authority": "^0.7.1",
26
23
  "clsx": "^2.1.1",
27
24
  "lucide-react": "^0.562.0",
25
+ "radix-ui": "^1.4.3",
28
26
  "react": "^19.2.0",
29
27
  "react-dom": "^19.2.0",
30
28
  "react-router": "^7.10.1",
@@ -1,16 +1,13 @@
1
1
  import { createBrowserRouter, RouterProvider } from "react-router";
2
- import { routes } from "@/routes";
2
+ import { routes } from "./routes";
3
3
  import { StrictMode } from "react";
4
4
  import { createRoot } from "react-dom/client";
5
- import { AuthProvider } from "./context/AuthContext";
6
5
  import "./styles/global.css";
7
6
 
8
7
  const router = createBrowserRouter(routes);
9
8
 
10
9
  createRoot(document.getElementById("root")!).render(
11
10
  <StrictMode>
12
- <AuthProvider>
13
- <RouterProvider router={router} />
14
- </AuthProvider>
11
+ <RouterProvider router={router} />
15
12
  </StrictMode>,
16
13
  );
@@ -0,0 +1,73 @@
1
+ import { AUTH_REDIRECT_PARAM } from "./authenticationConfig";
2
+ import { z } from "zod";
3
+
4
+ /** Email field validation */
5
+ export const emailSchema = z.string().trim().email("Please enter a valid email address");
6
+
7
+ /** Password field validation (minimum 8 characters) */
8
+ export const passwordSchema = z.string().min(8, "Password must be at least 8 characters");
9
+
10
+ /**
11
+ * Shared schema for new password + confirmation fields.
12
+ * Validates password length and matching confirmation.
13
+ */
14
+ export const newPasswordSchema = z
15
+ .object({
16
+ newPassword: passwordSchema,
17
+ confirmPassword: z.string().min(1, "Please confirm your password"),
18
+ })
19
+ .refine((data) => data.newPassword === data.confirmPassword, {
20
+ message: "Passwords do not match",
21
+ path: ["confirmPassword"],
22
+ });
23
+
24
+ /**
25
+ *
26
+ * Extracts the startUrl from URLSearchParams, defaulting to '/'.
27
+ *
28
+ * SECURITY NOTE: This function strictly validates the URL to prevent
29
+ * Open Redirect vulnerabilities. It allows only relative paths.
30
+ *
31
+ * @param searchParams - The URLSearchParams object from useSearchParams()
32
+ * @returns The start URL for post-authentication redirect
33
+ */
34
+ export function getStartUrl(searchParams: URLSearchParams): string {
35
+ // 1. Check for the standard redirect parameter
36
+ const url = searchParams.get(AUTH_REDIRECT_PARAM);
37
+ // 2. Security Check: Validation Logic
38
+ if (url && isValidRedirect(url)) {
39
+ return url;
40
+ }
41
+ // 3. Fallback: Default to root
42
+ return "/";
43
+ }
44
+
45
+ /**
46
+ * [Dev Note] Security: Validates that the redirect URL is a relative path
47
+ * to prevent Open Redirect vulnerabilities.
48
+ *
49
+ * Security Checks:
50
+ * 1. Rejects protocol-relative URLs (//)
51
+ * 2. Rejects backslash usage which some browsers treat as slashes (/\)
52
+ * 3. Rejects control characters
53
+ */
54
+ function isValidRedirect(url: string): boolean {
55
+ // Basic structure check
56
+ if (!url.startsWith("/") || url.startsWith("//")) return false;
57
+ // Security: Reject backslashes to prevent /\example.com bypasses
58
+ if (url.includes("\\")) return false;
59
+ // Robustness: Ensure it doesn't contain whitespace/control characters
60
+ if (/[^\u0021-\u00ff]/.test(url)) return false;
61
+ return true;
62
+ }
63
+
64
+ /**
65
+ * Shared response type for authentication endpoints (login/register).
66
+ * Success responses contain `success: true` and `redirectUrl`.
67
+ * Error responses contain `errors` array.
68
+ */
69
+ export interface AuthResponse {
70
+ success?: boolean;
71
+ redirectUrl?: string | null;
72
+ errors?: string[];
73
+ }
@@ -30,6 +30,15 @@ export const ROUTES = {
30
30
  },
31
31
  } as const;
32
32
 
33
+ /**
34
+ * [Dev Note] Centralized configuration for API endpoints.
35
+ * These are server-side endpoints, not client-side routes.
36
+ */
37
+ export const API_ROUTES = {
38
+ // W-21253864: Logout URL integration is not currently supported
39
+ LOGOUT: "/secur/logout.jsp",
40
+ } as const;
41
+
33
42
  /**
34
43
  * [Dev Note] Query parameter key used to store the return URL.
35
44
  * e.g. /login?startUrl=/profile
@@ -1,6 +1,6 @@
1
1
  import { Navigate, Outlet, useSearchParams } from "react-router";
2
2
  import { useAuth } from "../../context/AuthContext";
3
- import { getStartUrl } from "../../utils/helpers";
3
+ import { getStartUrl } from "./authHelpers";
4
4
  import { CardSkeleton } from "../layout/card-skeleton";
5
5
 
6
6
  /**
@@ -1,6 +1,6 @@
1
1
  import { Navigate, Outlet, useLocation } from "react-router";
2
2
  import { useAuth } from "../../context/AuthContext";
3
- import { AUTH_REDIRECT_PARAM, ROUTES } from "../../utils/authenticationConfig";
3
+ import { AUTH_REDIRECT_PARAM, ROUTES } from "./authenticationConfig";
4
4
  import { CardSkeleton } from "../layout/card-skeleton";
5
5
 
6
6
  /**