@collabdt/core 0.2.0 → 0.3.0

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 (117) hide show
  1. package/README.md +29 -21
  2. package/dist/core/components/AppSidebarContent.d.ts.map +1 -1
  3. package/dist/core/components/AppSidebarContent.js +21 -27
  4. package/dist/core/components/AppSidebarContent.js.map +1 -1
  5. package/dist/core/components/authentication/AuthPage.d.ts.map +1 -1
  6. package/dist/core/components/authentication/AuthPage.js +32 -7
  7. package/dist/core/components/authentication/AuthPage.js.map +1 -1
  8. package/dist/core/components/authentication/SignInAuthHeader.d.ts +7 -0
  9. package/dist/core/components/authentication/SignInAuthHeader.d.ts.map +1 -0
  10. package/dist/core/components/authentication/SignInAuthHeader.js +32 -0
  11. package/dist/core/components/authentication/SignInAuthHeader.js.map +1 -0
  12. package/dist/core/components/authentication/Signin.d.ts.map +1 -1
  13. package/dist/core/components/authentication/Signin.js +308 -10
  14. package/dist/core/components/authentication/Signin.js.map +1 -1
  15. package/dist/core/components/settings/index.js +3 -3
  16. package/dist/core/components/settings/index.js.map +1 -1
  17. package/dist/core/components/settings/src/OrganizationSettingsPanel.d.ts.map +1 -1
  18. package/dist/core/components/settings/src/OrganizationSettingsPanel.js +5 -4
  19. package/dist/core/components/settings/src/OrganizationSettingsPanel.js.map +1 -1
  20. package/dist/core/components/settings/src/SettingsSidebar.d.ts.map +1 -1
  21. package/dist/core/components/settings/src/SettingsSidebar.js +12 -2
  22. package/dist/core/components/settings/src/SettingsSidebar.js.map +1 -1
  23. package/dist/core/components/support/BugReportDialog.d.ts.map +1 -1
  24. package/dist/core/components/support/BugReportDialog.js +94 -13
  25. package/dist/core/components/support/BugReportDialog.js.map +1 -1
  26. package/dist/core/components/support/FeatureRequestDialog.d.ts.map +1 -1
  27. package/dist/core/components/support/FeatureRequestDialog.js +33 -6
  28. package/dist/core/components/support/FeatureRequestDialog.js.map +1 -1
  29. package/dist/core/components/ui/AppSidebar.d.ts.map +1 -1
  30. package/dist/core/components/ui/AppSidebar.js +52 -9
  31. package/dist/core/components/ui/AppSidebar.js.map +1 -1
  32. package/dist/core/components/ui/DataTable.js +3 -3
  33. package/dist/core/components/ui/DataTable.js.map +1 -1
  34. package/dist/core/components/ui/Dialog.js +1 -1
  35. package/dist/core/components/ui/Dialog.js.map +1 -1
  36. package/dist/core/components/ui/InfoSidebar/Container.js +1 -1
  37. package/dist/core/components/ui/InfoSidebar/Container.js.map +1 -1
  38. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.d.ts.map +1 -1
  39. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.js +2 -2
  40. package/dist/core/components/ui/Sensors/CollapsibleSensorItem.js.map +1 -1
  41. package/dist/core/components/ui/Sensors/SensorsSection.d.ts.map +1 -1
  42. package/dist/core/components/ui/Sensors/SensorsSection.js +2 -1
  43. package/dist/core/components/ui/Sensors/SensorsSection.js.map +1 -1
  44. package/dist/core/components/ui/Sensors/sensorUtils.d.ts +9 -0
  45. package/dist/core/components/ui/Sensors/sensorUtils.d.ts.map +1 -1
  46. package/dist/core/components/ui/Sensors/sensorUtils.js +6 -0
  47. package/dist/core/components/ui/Sensors/sensorUtils.js.map +1 -1
  48. package/dist/core/components/ui/Sidebar.d.ts +4 -0
  49. package/dist/core/components/ui/Sidebar.d.ts.map +1 -1
  50. package/dist/core/components/ui/Sidebar.js +11 -5
  51. package/dist/core/components/ui/Sidebar.js.map +1 -1
  52. package/dist/core/components/ui/Table.js +2 -2
  53. package/dist/core/components/ui/Table.js.map +1 -1
  54. package/dist/core/components/viewers/Data/DataMenu.d.ts.map +1 -1
  55. package/dist/core/components/viewers/Data/DataMenu.js +8 -8
  56. package/dist/core/components/viewers/Data/DataMenu.js.map +1 -1
  57. package/dist/core/components/viewers/Data/buildingDetails/BuildingDetails.d.ts.map +1 -1
  58. package/dist/core/components/viewers/Data/buildingDetails/BuildingDetails.js +26 -0
  59. package/dist/core/components/viewers/Data/buildingDetails/BuildingDetails.js.map +1 -1
  60. package/dist/core/components/viewers/Data/details/DetailHeader.js +14 -14
  61. package/dist/core/components/viewers/Data/details/DetailHeader.js.map +1 -1
  62. package/dist/core/components/viewers/Data/details/TabSidebar.d.ts.map +1 -1
  63. package/dist/core/components/viewers/Data/details/TabSidebar.js +22 -0
  64. package/dist/core/components/viewers/Data/details/TabSidebar.js.map +1 -1
  65. package/dist/core/components/viewers/Data/infrastructureDetails/InfrastructureDetails.d.ts.map +1 -1
  66. package/dist/core/components/viewers/Data/infrastructureDetails/InfrastructureDetails.js +19 -0
  67. package/dist/core/components/viewers/Data/infrastructureDetails/InfrastructureDetails.js.map +1 -1
  68. package/dist/core/components/viewers/Data/siteDetails/SiteDetails.d.ts.map +1 -1
  69. package/dist/core/components/viewers/Data/siteDetails/SiteDetails.js +19 -0
  70. package/dist/core/components/viewers/Data/siteDetails/SiteDetails.js.map +1 -1
  71. package/dist/core/components/viewers/Data/utils/Columns.js +2 -2
  72. package/dist/core/components/viewers/Data/utils/Columns.js.map +1 -1
  73. package/dist/core/components/viewers/Data/utils/positionParser.d.ts.map +1 -1
  74. package/dist/core/components/viewers/Data/utils/positionParser.js +6 -5
  75. package/dist/core/components/viewers/Data/utils/positionParser.js.map +1 -1
  76. package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/src/TopicsSection.d.ts.map +1 -1
  77. package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/src/TopicsSection.js +8 -1
  78. package/dist/core/components/viewers/bim/src/BimSidebar/src/CommunicationTab/src/TopicsSection.js.map +1 -1
  79. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.d.ts.map +1 -1
  80. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.js +7 -1
  81. package/dist/core/components/viewers/bim/src/BimSidebar/src/FileTab/src/FilesSection.js.map +1 -1
  82. package/dist/core/components/viewers/map/datasets/RowActions.js +6 -6
  83. package/dist/core/components/viewers/map/datasets/RowActions.js.map +1 -1
  84. package/dist/core/components/viewers/map/datasets/data.js +1 -1
  85. package/dist/core/components/viewers/map/datasets/data.js.map +1 -1
  86. package/dist/core/components/viewers/map/datasets/index.d.ts.map +1 -1
  87. package/dist/core/components/viewers/map/datasets/index.js +28 -9
  88. package/dist/core/components/viewers/map/datasets/index.js.map +1 -1
  89. package/dist/core/components/viewers/pointcloud/src/PointCloudLoadingState/index.d.ts.map +1 -1
  90. package/dist/core/components/viewers/pointcloud/src/PointCloudLoadingState/index.js +54 -31
  91. package/dist/core/components/viewers/pointcloud/src/PointCloudLoadingState/index.js.map +1 -1
  92. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/index.js +1 -1
  93. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/index.js.map +1 -1
  94. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/PointCloudSection.d.ts +2 -1
  95. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/PointCloudSection.d.ts.map +1 -1
  96. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/PointCloudSection.js +5 -4
  97. package/dist/core/components/viewers/pointcloud/src/PointCloudSidebar/src/FileTab/src/PointCloudSection.js.map +1 -1
  98. package/dist/core/hooks/useCaptureScreenshot.d.ts.map +1 -1
  99. package/dist/core/hooks/useCaptureScreenshot.js +62 -31
  100. package/dist/core/hooks/useCaptureScreenshot.js.map +1 -1
  101. package/dist/core/hooks/useCurrentViewerPosition.d.ts +18 -0
  102. package/dist/core/hooks/useCurrentViewerPosition.d.ts.map +1 -0
  103. package/dist/core/hooks/useCurrentViewerPosition.js +66 -0
  104. package/dist/core/hooks/useCurrentViewerPosition.js.map +1 -0
  105. package/dist/core/hooks/useShareUrl.d.ts +2 -0
  106. package/dist/core/hooks/useShareUrl.d.ts.map +1 -0
  107. package/dist/core/hooks/useShareUrl.js +74 -0
  108. package/dist/core/hooks/useShareUrl.js.map +1 -0
  109. package/dist/core/i18n/index.d.ts +8 -0
  110. package/dist/core/i18n/index.d.ts.map +1 -0
  111. package/dist/core/i18n/index.js +8 -0
  112. package/dist/core/i18n/index.js.map +1 -0
  113. package/dist/core/i18n/messages/en.json +1873 -0
  114. package/dist/core/i18n/messages/es.json +1870 -0
  115. package/dist/core/i18n/messages/fr.json +1870 -0
  116. package/dist/core/styles/globals.css +46 -33
  117. package/package.json +9 -5
@@ -9,6 +9,7 @@ import { Button, GoogleIcon, Input, LoadingSpinner } from "../ui";
9
9
  import { AuthPage, useAuthTheme } from "./AuthPage";
10
10
  import { useParams, useSearchParams } from "next/navigation";
11
11
  import ReCAPTCHA from "react-google-recaptcha";
12
+ import { PasswordError } from "../authentication/PasswordError";
12
13
  function SignInContent({ recaptchaSiteKey }) {
13
14
  var _a;
14
15
  const [step, setStep] = React.useState("login");
@@ -21,6 +22,16 @@ function SignInContent({ recaptchaSiteKey }) {
21
22
  const [isLoading, setIsLoading] = React.useState(false);
22
23
  const [error, setError] = React.useState("");
23
24
  const [showPassword, setShowPassword] = React.useState(false);
25
+ const [confirmPassword, setConfirmPassword] = React.useState("");
26
+ const [showNewPassword, setShowNewPassword] = React.useState(false);
27
+ const [showConfirmPassword, setShowConfirmPassword] = React.useState(false);
28
+ const [currentPassword, setCurrentPassword] = React.useState("");
29
+ const [newPassword, setNewPassword] = React.useState("");
30
+ const [newPasswordErrors, setNewPasswordErrors] = React.useState([]);
31
+ const [passwordErrors, setPasswordErrors] = React.useState([]);
32
+ const [confirmPasswordError, setConfirmPasswordError] = React.useState("");
33
+ const [hasAttemptedSave, setHasAttemptedSave] = React.useState(false);
34
+ const [hasAttemptedSubmit, setHasAttemptedSubmit] = React.useState(false);
24
35
  const searchParams = useSearchParams();
25
36
  const params = useParams();
26
37
  const orgName = (_a = params.instance) != null ? _a : "canada";
@@ -34,6 +45,8 @@ function SignInContent({ recaptchaSiteKey }) {
34
45
  }, [googleError, orgName]);
35
46
  const t = useTranslations("Signin");
36
47
  const tMfa = useTranslations("MFA");
48
+ const tforgotPassword = useTranslations("forgotPassword");
49
+ const tresetPassword = useTranslations("resetPassword");
37
50
  const authTheme = useAuthTheme();
38
51
  const resetCaptcha = () => {
39
52
  var _a2;
@@ -121,18 +134,131 @@ function SignInContent({ recaptchaSiteKey }) {
121
134
  setIsLoading(false);
122
135
  }
123
136
  };
137
+ const validatePassword = (password2) => {
138
+ const errors = [];
139
+ const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^a-zA-Z\d\s])[^\s]{12,65}$/;
140
+ if (!passwordRegex.test(password2)) {
141
+ errors.push(t("weakPassword"));
142
+ }
143
+ return errors;
144
+ };
145
+ const handlePasswordChange = (e) => {
146
+ const value = e.target.value;
147
+ setNewPassword(value);
148
+ setNewPasswordErrors(validatePassword(value));
149
+ if (confirmPassword) {
150
+ setConfirmPasswordError(value === confirmPassword ? "" : tforgotPassword("noMatch"));
151
+ }
152
+ };
153
+ const handleConfirmPasswordChange = (e) => {
154
+ const value = e.target.value;
155
+ setConfirmPassword(value);
156
+ setConfirmPasswordError(value === newPassword ? "" : tforgotPassword("noMatch"));
157
+ };
158
+ const handleForgotPassword = async () => {
159
+ setIsLoading(true);
160
+ setError("");
161
+ try {
162
+ const res = await fetch("/api/forgotpassword", {
163
+ method: "POST",
164
+ headers: {
165
+ "Content-Type": "application/json"
166
+ },
167
+ body: JSON.stringify({
168
+ email
169
+ })
170
+ });
171
+ if (!res.ok) {
172
+ setError("Unable to send password reset email.");
173
+ setIsLoading(false);
174
+ return;
175
+ }
176
+ setStep("forgotPasswordSent");
177
+ setIsLoading(false);
178
+ } catch (e) {
179
+ setError("Unable to process");
180
+ setIsLoading(false);
181
+ }
182
+ };
183
+ const handleVerifyOTPForPasswordChange = async () => {
184
+ setIsLoading(true);
185
+ setError("");
186
+ try {
187
+ const res = await fetch("/api/verifyotp", {
188
+ method: "POST",
189
+ headers: {
190
+ "Content-Type": "application/json"
191
+ },
192
+ body: JSON.stringify({
193
+ email,
194
+ code
195
+ })
196
+ });
197
+ if (!res.ok) {
198
+ toast.error("Invalid verification code.");
199
+ setIsLoading(false);
200
+ return;
201
+ }
202
+ toast.success("SUCCESS");
203
+ setStep("changePassword");
204
+ } catch (e) {
205
+ setError("Unable to verify code.");
206
+ } finally {
207
+ setIsLoading(false);
208
+ }
209
+ };
210
+ const handleResetPassword = async () => {
211
+ setHasAttemptedSubmit(true);
212
+ const errors = validatePassword(newPassword);
213
+ setPasswordErrors(errors);
214
+ if (newPassword !== confirmPassword) {
215
+ toast.error(tforgotPassword("noMatch"));
216
+ return;
217
+ }
218
+ if (errors.length > 0) {
219
+ toast.error(tforgotPassword("passwordPolicyError"));
220
+ return;
221
+ }
222
+ setIsLoading(true);
223
+ setError("");
224
+ try {
225
+ const res = await fetch("/api/resetpassword", {
226
+ method: "POST",
227
+ headers: {
228
+ "Content-Type": "application/json"
229
+ },
230
+ body: JSON.stringify({
231
+ email,
232
+ code,
233
+ newPassword
234
+ })
235
+ });
236
+ if (!res.ok) {
237
+ toast.error("Session Expired: Unable to reset password.");
238
+ setStep("login");
239
+ return;
240
+ }
241
+ toast.success("Password successfully changed.");
242
+ setNewPassword("");
243
+ setConfirmPassword("");
244
+ setCode("");
245
+ setStep("login");
246
+ } finally {
247
+ setIsLoading(false);
248
+ }
249
+ };
124
250
  return /* @__PURE__ */ jsxs(Fragment, { children: [
125
251
  /* @__PURE__ */ jsx(Toaster, { richColors: true, position: "top-right" }),
126
- /* @__PURE__ */ jsxs("div", { className: "space-y-2 text-left", children: [
127
- /* @__PURE__ */ jsx("h1", { className: "font-display font-bold", style: {
128
- fontSize: "1.75rem",
129
- lineHeight: "1.1",
130
- letterSpacing: "-0.02em",
131
- color: "var(--hp-on-surface)"
132
- }, children: step === "login" ? t("title") : tMfa("title") }),
133
- /* @__PURE__ */ jsx("p", { style: { color: "var(--hp-on-surface-variant)", fontSize: "0.9rem" }, children: step === "login" ? t("message") : tMfa("subtitle", { email }) })
134
- ] }),
135
252
  step === "login" && /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
253
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2 text-left", children: [
254
+ /* @__PURE__ */ jsx("h1", { className: "font-display font-bold", style: {
255
+ fontSize: "1.75rem",
256
+ lineHeight: "1.1",
257
+ letterSpacing: "-0.02em",
258
+ color: "var(--hp-on-surface)"
259
+ }, children: t("title") }),
260
+ /* @__PURE__ */ jsx("p", { style: { color: "var(--hp-on-surface-variant)", fontSize: "0.9rem" }, children: t("message") })
261
+ ] }),
136
262
  /* @__PURE__ */ jsx(
137
263
  Input,
138
264
  {
@@ -184,9 +310,31 @@ function SignInContent({ recaptchaSiteKey }) {
184
310
  children: /* @__PURE__ */ jsx(GoogleIcon, { size: 20 })
185
311
  }
186
312
  )
187
- ] })
313
+ ] }),
314
+ /* @__PURE__ */ jsx(
315
+ "button",
316
+ {
317
+ type: "button",
318
+ onClick: () => {
319
+ setError("");
320
+ setStep("forgotPassword");
321
+ },
322
+ className: "text-sm underline underline-offset-4 hover:opacity-80",
323
+ style: { color: "var(--hp-primary)" },
324
+ children: "Reset your password"
325
+ }
326
+ )
188
327
  ] }),
189
328
  step === "mfa" && /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
329
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2 text-left", children: [
330
+ /* @__PURE__ */ jsx("h1", { className: "font-display font-bold", style: {
331
+ fontSize: "1.75rem",
332
+ lineHeight: "1.1",
333
+ letterSpacing: "-0.02em",
334
+ color: "var(--hp-on-surface)"
335
+ }, children: tMfa("title") }),
336
+ /* @__PURE__ */ jsx("p", { style: { color: "var(--hp-on-surface-variant)", fontSize: "0.9rem" }, children: tMfa("subtitle", { email }) })
337
+ ] }),
190
338
  /* @__PURE__ */ jsx(
191
339
  Input,
192
340
  {
@@ -210,6 +358,156 @@ function SignInContent({ recaptchaSiteKey }) {
210
358
  }
211
359
  )
212
360
  ] }),
361
+ step === "forgotPassword" && /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
362
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2 text-left", children: [
363
+ /* @__PURE__ */ jsx("h1", { className: "font-display font-bold", style: {
364
+ fontSize: "1.75rem",
365
+ lineHeight: "1.1",
366
+ letterSpacing: "-0.02em",
367
+ color: "var(--hp-on-surface)"
368
+ }, children: tresetPassword("title") }),
369
+ /* @__PURE__ */ jsx("p", { style: { color: "var(--hp-on-surface-variant)", fontSize: "0.9rem" }, children: tresetPassword("subtitle") })
370
+ ] }),
371
+ /* @__PURE__ */ jsx(
372
+ Input,
373
+ {
374
+ type: "email",
375
+ placeholder: "Enter your email address",
376
+ value: email,
377
+ onChange: (e) => setEmail(e.target.value),
378
+ disabled: isLoading
379
+ }
380
+ ),
381
+ error && /* @__PURE__ */ jsx("div", { className: "auth-pw-error", children: error }),
382
+ /* @__PURE__ */ jsx(
383
+ Button,
384
+ {
385
+ onClick: handleForgotPassword,
386
+ disabled: isLoading || !email,
387
+ className: "w-full",
388
+ children: isLoading ? /* @__PURE__ */ jsx(LoadingSpinner, {}) : "Send Reset Link"
389
+ }
390
+ ),
391
+ /* @__PURE__ */ jsxs(
392
+ Button,
393
+ {
394
+ variant: "outline",
395
+ onClick: () => setStep("login"),
396
+ className: "w-full",
397
+ children: [
398
+ /* @__PURE__ */ jsx(LR.ArrowLeft, { size: 16 }),
399
+ "Back to Login"
400
+ ]
401
+ }
402
+ )
403
+ ] }),
404
+ step === "forgotPasswordSent" && /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
405
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2 text-left", children: [
406
+ /* @__PURE__ */ jsx("h1", { className: "font-display font-bold", style: {
407
+ fontSize: "1.75rem",
408
+ lineHeight: "1.1",
409
+ letterSpacing: "-0.02em",
410
+ color: "var(--hp-on-surface)"
411
+ }, children: tresetPassword("title") }),
412
+ /* @__PURE__ */ jsx("p", { style: { color: "var(--hp-on-surface-variant)", fontSize: "0.9rem" }, children: tresetPassword("ifAnAccountExists", { email }) })
413
+ ] }),
414
+ /* @__PURE__ */ jsx(
415
+ Input,
416
+ {
417
+ placeholder: tMfa("placeholder"),
418
+ value: code,
419
+ onChange: (e) => setCode(e.target.value),
420
+ disabled: isLoading
421
+ }
422
+ ),
423
+ error && /* @__PURE__ */ jsx("div", { className: "auth-pw-error", children: error }),
424
+ /* @__PURE__ */ jsx(Button, { onClick: handleVerifyOTPForPasswordChange, disabled: isLoading, className: "w-full", children: isLoading ? /* @__PURE__ */ jsx(LoadingSpinner, {}) : tMfa("verify") }),
425
+ /* @__PURE__ */ jsx(
426
+ Button,
427
+ {
428
+ onClick: () => setStep("login"),
429
+ className: "w-full",
430
+ children: "Back to Login"
431
+ }
432
+ )
433
+ ] }),
434
+ step === "changePassword" && /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
435
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2 text-left", children: [
436
+ /* @__PURE__ */ jsx("h1", { className: "font-display font-bold", style: {
437
+ fontSize: "1.75rem",
438
+ lineHeight: "1.1",
439
+ letterSpacing: "-0.02em",
440
+ color: "var(--hp-on-surface)"
441
+ }, children: tresetPassword("newPasswordTitle") }),
442
+ /* @__PURE__ */ jsxs("p", { style: { color: "var(--hp-on-surface-variant)", fontSize: "0.9rem" }, children: [
443
+ tresetPassword("newPasswordMessage"),
444
+ /* @__PURE__ */ jsx("br", {}),
445
+ " ",
446
+ /* @__PURE__ */ jsx("br", {}),
447
+ tresetPassword("lowercase"),
448
+ " ",
449
+ /* @__PURE__ */ jsx("br", {}),
450
+ tresetPassword("lowercase"),
451
+ " ",
452
+ /* @__PURE__ */ jsx("br", {}),
453
+ tresetPassword("uppercase"),
454
+ " ",
455
+ /* @__PURE__ */ jsx("br", {}),
456
+ tresetPassword("digit"),
457
+ " ",
458
+ /* @__PURE__ */ jsx("br", {}),
459
+ tresetPassword("specialchar"),
460
+ " ",
461
+ /* @__PURE__ */ jsx("br", {}),
462
+ tresetPassword("minmax"),
463
+ " ",
464
+ /* @__PURE__ */ jsx("br", {})
465
+ ] })
466
+ ] }),
467
+ /* @__PURE__ */ jsx(
468
+ Input,
469
+ {
470
+ type: showNewPassword ? "text" : "password",
471
+ placeholder: "New Password",
472
+ className: `w-full ${hasAttemptedSave && newPasswordErrors.length > 0 ? "border-destructive" : ""}`,
473
+ value: newPassword,
474
+ onChange: handlePasswordChange
475
+ }
476
+ ),
477
+ hasAttemptedSave && newPasswordErrors.map((error2, idx) => /* @__PURE__ */ jsx(PasswordError, { message: error2 }, idx)),
478
+ /* @__PURE__ */ jsx(
479
+ Input,
480
+ {
481
+ type: showConfirmPassword ? "text" : "password",
482
+ placeholder: "Confirm Password",
483
+ value: confirmPassword,
484
+ onChange: handleConfirmPasswordChange
485
+ }
486
+ ),
487
+ hasAttemptedSave && confirmPasswordError && /* @__PURE__ */ jsx(PasswordError, { message: confirmPasswordError }),
488
+ error && /* @__PURE__ */ jsx("div", { className: "auth-pw-error", children: error }),
489
+ /* @__PURE__ */ jsx(
490
+ Button,
491
+ {
492
+ onClick: handleResetPassword,
493
+ disabled: isLoading,
494
+ className: "w-full",
495
+ children: isLoading ? /* @__PURE__ */ jsx(LoadingSpinner, {}) : "Change Password"
496
+ }
497
+ ),
498
+ /* @__PURE__ */ jsxs(
499
+ Button,
500
+ {
501
+ variant: "outline",
502
+ onClick: () => setStep("login"),
503
+ className: "w-full",
504
+ children: [
505
+ /* @__PURE__ */ jsx(LR.ArrowLeft, { size: 16 }),
506
+ "Back to Login"
507
+ ]
508
+ }
509
+ )
510
+ ] }),
213
511
  step === "login" && /* @__PURE__ */ jsx("div", { className: "auth-captcha-wrapper", children: /* @__PURE__ */ jsx(
214
512
  ReCAPTCHA,
215
513
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/core/components/authentication/Signin.tsx"],"sourcesContent":["'use client'\r\n\r\n// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as React from 'react'\r\nimport { signIn } from 'next-auth/react'\r\nimport { useTranslations } from 'next-intl'\r\nimport * as LR from 'lucide-react'\r\nimport { toast, Toaster } from 'sonner'\r\nimport { Button, GoogleIcon, Input, LoadingSpinner } from '../ui'\r\nimport { AuthPage, useAuthTheme } from './AuthPage'\r\nimport { useParams, useSearchParams } from 'next/navigation'\r\nimport ReCAPTCHA from 'react-google-recaptcha'\r\n//import { useAppConfigContext } from '../../store/AppConfig/context'\r\n\r\ninterface SignInContentProps {\r\n recaptchaSiteKey?: string\r\n}\r\n\r\nfunction SignInContent({ recaptchaSiteKey, }) {\r\n const [step, setStep] = React.useState<'login' | 'mfa'>('login')\r\n\r\n const [email, setEmail] = React.useState('')\r\n const [password, setPassword] = React.useState('')\r\n const [code, setCode] = React.useState('')\r\n\r\n const recaptchaRef = React.useRef<ReCAPTCHA>(null)\r\n const [captchaStatus, setCaptchaStatus] = React.useState(false)\r\n const [captchaToken, setCaptchaToken] = React.useState('')\r\n const [isLoading, setIsLoading] = React.useState(false)\r\n const [error, setError] = React.useState('')\r\n const [showPassword, setShowPassword] = React.useState(false)\r\n\r\n const searchParams = useSearchParams()\r\n const params = useParams()\r\n const orgName = params.instance ?? 'canada'\r\n const [googleError, setGoogleError] = React.useState(\r\n searchParams.get('error')\r\n )\r\n //Clean up the Google query error in URL, and have it only return /orgName/signin to clear frontend error responses \r\n React.useEffect(() => {\r\n if (googleError) {\r\n window.history.replaceState({}, '', `/${orgName}/signin`)\r\n }\r\n }, [googleError, orgName])\r\n\r\n const t = useTranslations('Signin')\r\n const tMfa = useTranslations('MFA')\r\n const authTheme = useAuthTheme()\r\n\r\n \r\n\r\n const resetCaptcha = () => {\r\n recaptchaRef.current?.reset()\r\n setCaptchaToken('')\r\n setCaptchaStatus(false)\r\n }\r\n\r\n const onReCaptchaSuccess = (token) => {\r\n setCaptchaToken(token)\r\n setCaptchaStatus(true)\r\n }\r\n\r\n // Initial LOGIN\r\n const handleSubmit = async (e) => {\r\n e.preventDefault()\r\n setGoogleError(null)\r\n setIsLoading(true)\r\n setError('')\r\n\r\n try {\r\n const result = await signIn('credentials', {\r\n redirect: false,\r\n email,\r\n password,\r\n captchaToken,\r\n })\r\n\r\n if (result?.error) {\r\n\r\n if (result.code === 'rate_limit_error') {\r\n\r\n setIsLoading(true)\r\n setError('Too many failed login attempts. Please try again later.')\r\n return\r\n }\r\n\r\n else if (result.code === 'whitelist_invalid_credentials') {\r\n setError('Invalid email or password')\r\n setIsLoading(false)\r\n resetCaptcha()\r\n return\r\n }\r\n\r\n else if (!captchaStatus) {\r\n setError('Captcha Verification Failed.')\r\n setIsLoading(false)\r\n resetCaptcha()\r\n return\r\n }\r\n\r\n else if (result.code === 'invalid_credentials') {\r\n setError('Invalid email or password')\r\n setIsLoading(false)\r\n resetCaptcha()\r\n return\r\n }\r\n //MFA TRIGGER\r\n else if (result.code === 'mfa_required') {\r\n setStep('mfa')\r\n setIsLoading(false)\r\n return\r\n }\r\n\r\n else { //result.code === 'expired_recaptcha_token\r\n setError('Captcha Verification Expired. Please try again later.')\r\n setIsLoading(false)\r\n resetCaptcha()\r\n return\r\n }\r\n }\r\n\r\n // Completed Login + MFA - Redirect to the Platform's Organization Dashboard \r\n window.location.href = `/${orgName}`\r\n\r\n } catch (err) {\r\n setError('Unexpected error. Please try again.')\r\n setIsLoading(false)\r\n }\r\n }\r\n\r\n // VERIFY OTP for MFA\r\n const handleVerifyOTP = async () => {\r\n setIsLoading(true)\r\n setError('')\r\n\r\n try {\r\n const res = await fetch('/api/mfa', {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ email, code }),\r\n })\r\n\r\n if (!res.ok) {\r\n toast.error(tMfa('invalidCode'))\r\n setIsLoading(false)\r\n return\r\n }\r\n\r\n toast.success(tMfa('success'))\r\n\r\n // FINAL LOGIN after successful MFA process\r\n await signIn('credentials', {\r\n email,\r\n password,\r\n mfaVerified: true,\r\n redirect: true,\r\n redirectTo: `/${orgName}`,\r\n })\r\n\r\n } catch (err) {\r\n toast.error(tMfa('verificationFailed'))\r\n setIsLoading(false)\r\n }\r\n }\r\n\r\n return (\r\n <>\r\n <Toaster richColors position=\"top-right\" />\r\n {/* Header */}\r\n <div className=\"space-y-2 text-left\">\r\n <h1 className=\"font-display font-bold\" style={{\r\n fontSize: '1.75rem',\r\n lineHeight: '1.1',\r\n letterSpacing: '-0.02em',\r\n color: 'var(--hp-on-surface)',\r\n }}>\r\n {step === 'login' ? t('title') : tMfa('title')}\r\n </h1>\r\n\r\n <p style={{ color: 'var(--hp-on-surface-variant)', fontSize: '0.9rem' }}>\r\n {step === 'login'\r\n ? t('message')\r\n : tMfa('subtitle', { email })}\r\n </p>\r\n </div>\r\n\r\n {/* LOGIN FORM */}\r\n {step === 'login' && (\r\n <form onSubmit={handleSubmit} className=\"space-y-4\">\r\n\r\n <Input\r\n type=\"email\"\r\n placeholder={t('placeholder1')}\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n disabled={isLoading}\r\n required\r\n />\r\n\r\n <div className=\"relative\">\r\n <Input\r\n type={showPassword ? 'text' : 'password'}\r\n placeholder={t('placeholder2')}\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n disabled={isLoading}\r\n required\r\n className=\"pr-10\"\r\n />\r\n <button\r\n type=\"button\"\r\n onClick={() => setShowPassword(v => !v)}\r\n tabIndex={-1}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 transition-colors\"\r\n style={{ color: 'var(--hp-on-surface-variant)' }}\r\n >\r\n {showPassword ? <LR.EyeOff size={16} /> : <LR.Eye size={16} />}\r\n </button>\r\n </div>\r\n {/* Google Not Linked Error */}\r\n {googleError === 'google_not_linked' && (\r\n <div className=\"auth-pw-error\">\r\n Your Google account is not linked. Please sign in with your credentials first, then link your Google account.\r\n </div>\r\n )}\r\n {error && <div className=\"auth-pw-error\">{error}</div>}\r\n\r\n <div className=\"flex items-center gap-2\">\r\n <Button type=\"submit\" disabled={isLoading} className=\"flex-1 auth-btn-primary\">\r\n {isLoading ? <LoadingSpinner /> : 'Login'}\r\n </Button>\r\n\r\n {/* Google button */}\r\n {<button\r\n type=\"button\"\r\n onClick={() => signIn('google', { redirectTo: `/${orgName}` })}\r\n disabled={isLoading}\r\n aria-label=\"Sign in with Google\"\r\n className=\"auth-google-btn\"\r\n >\r\n <GoogleIcon size={20} />\r\n </button>}\r\n\r\n </div>\r\n\r\n {/*⚠️⚠️⚠️⚠️ DISABLED FOR NOW - Password Reset link, will implement in the future when we have the flow ready */}\r\n {/* Reset Password link */}\r\n {/* <div className=\"flex justify-start\">\r\n <a\r\n href={`/${orgName}/auth/reset-password`}\r\n className=\"text-sm underline underline-offset-4 hover:opacity-80\"\r\n style={{ color: 'var(--hp-primary)' }}\r\n >\r\n Reset your password\r\n </a>\r\n </div> */}\r\n </form>\r\n )}\r\n\r\n {/* MFA FORM */}\r\n {step === 'mfa' && (\r\n <div className=\"space-y-4\">\r\n\r\n <Input\r\n placeholder={tMfa('placeholder')}\r\n value={code}\r\n onChange={(e) => setCode(e.target.value)}\r\n disabled={isLoading}\r\n />\r\n\r\n <Button onClick={handleVerifyOTP} disabled={isLoading} className=\"w-full\">\r\n {isLoading ? <LoadingSpinner /> : tMfa('verify')}\r\n </Button>\r\n\r\n {/* Back */}\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => setStep('login')}\r\n className=\"w-full mt-3 inline-flex items-center justify-center gap-2\"\r\n >\r\n <LR.ArrowLeft size={16} />\r\n {tMfa('backToLogin')}\r\n </Button>\r\n </div>\r\n )}\r\n\r\n {/* CAPTCHA only on Credentials(Username and Password) Provider login */}\r\n \r\n {step === 'login' && (\r\n <div className=\"auth-captcha-wrapper\">\r\n <ReCAPTCHA\r\n ref={recaptchaRef}\r\n key={`recaptcha-${authTheme}`}\r\n sitekey={recaptchaSiteKey ?? ''}\r\n onChange={(token) => onReCaptchaSuccess(token)}\r\n theme={authTheme}\r\n />\r\n </div>\r\n )}\r\n </>\r\n )\r\n}\r\n\r\ninterface SignInProps {\r\n recaptchaSiteKey?: string\r\n minioBaseUrl?: string\r\n}\r\n\r\nexport function SignIn({ recaptchaSiteKey,minioBaseUrl, }: SignInProps) {\r\n return (\r\n <AuthPage minioBaseUrl={minioBaseUrl}>\r\n <SignInContent recaptchaSiteKey={recaptchaSiteKey} />\r\n </AuthPage>\r\n )\r\n}"],"mappings":"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","names":["_a"]}
1
+ {"version":3,"sources":["../../../../src/core/components/authentication/Signin.tsx"],"sourcesContent":["'use client'\r\n\r\n// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as React from 'react'\r\nimport { signIn } from 'next-auth/react'\r\nimport { useTranslations } from 'next-intl'\r\nimport * as LR from 'lucide-react'\r\nimport { toast, Toaster } from 'sonner'\r\nimport { Button, GoogleIcon, Input, LoadingSpinner } from '../ui'\r\nimport { AuthPage, useAuthTheme } from './AuthPage'\r\nimport { useParams, useSearchParams } from 'next/navigation'\r\nimport ReCAPTCHA from 'react-google-recaptcha'\r\nimport { PasswordError } from '../authentication/PasswordError'\r\nimport { AuthHeader } from './SignInAuthHeader'\r\n//import { useAppConfigContext } from '../../store/AppConfig/context'\r\n\r\ninterface SignInContentProps {\r\n recaptchaSiteKey?: string\r\n}\r\n\r\nfunction SignInContent({ recaptchaSiteKey, }) {\r\n const [step, setStep] = React.useState<\r\n 'login'\r\n | 'mfa'\r\n | 'forgotPassword'\r\n | 'forgotPasswordSent'\r\n | 'changePassword'\r\n>('login')\r\n\r\n const [email, setEmail] = React.useState('')\r\n const [password, setPassword] = React.useState('')\r\n const [code, setCode] = React.useState('')\r\n\r\n const recaptchaRef = React.useRef<ReCAPTCHA>(null)\r\n const [captchaStatus, setCaptchaStatus] = React.useState(false)\r\n const [captchaToken, setCaptchaToken] = React.useState('')\r\n const [isLoading, setIsLoading] = React.useState(false)\r\n const [error, setError] = React.useState('')\r\n const [showPassword, setShowPassword] = React.useState(false)\r\n const [confirmPassword, setConfirmPassword] = React.useState('')\r\n\r\n const [showNewPassword, setShowNewPassword] = React.useState(false)\r\n const [showConfirmPassword, setShowConfirmPassword] = React.useState(false)\r\n const [currentPassword, setCurrentPassword] = React.useState('')\r\n const [newPassword, setNewPassword] = React.useState('')\r\n\r\n const [newPasswordErrors, setNewPasswordErrors] = React.useState<string[]>([])\r\n const [passwordErrors, setPasswordErrors] = React.useState<string[]>([])\r\n const [confirmPasswordError, setConfirmPasswordError] = React.useState('')\r\n const [hasAttemptedSave, setHasAttemptedSave] = React.useState(false)\r\n const [hasAttemptedSubmit, setHasAttemptedSubmit] = React.useState(false)\r\n \r\n\r\n const searchParams = useSearchParams()\r\n const params = useParams()\r\n const orgName = params.instance ?? 'canada'\r\n const [googleError, setGoogleError] = React.useState(\r\n searchParams.get('error')\r\n )\r\n //Clean up the Google query error in URL, and have it only return /orgName/signin to clear frontend error responses \r\n React.useEffect(() => {\r\n if (googleError) {\r\n window.history.replaceState({}, '', `/${orgName}/signin`)\r\n }\r\n }, [googleError, orgName])\r\n\r\n const t = useTranslations('Signin')\r\n const tMfa = useTranslations('MFA')\r\n const tforgotPassword = useTranslations('forgotPassword')\r\n const tresetPassword = useTranslations('resetPassword')\r\n const authTheme = useAuthTheme()\r\n\r\n \r\n\r\n const resetCaptcha = () => {\r\n recaptchaRef.current?.reset()\r\n setCaptchaToken('')\r\n setCaptchaStatus(false)\r\n }\r\n\r\n const onReCaptchaSuccess = (token) => {\r\n setCaptchaToken(token)\r\n setCaptchaStatus(true)\r\n }\r\n\r\n // Initial LOGIN with Credentials(Username and Password)\r\n const handleSubmit = async (e) => {\r\n e.preventDefault()\r\n setGoogleError(null)\r\n setIsLoading(true)\r\n setError('')\r\n\r\n try {\r\n const result = await signIn('credentials', {\r\n redirect: false,\r\n email,\r\n password,\r\n captchaToken,\r\n })\r\n\r\n if (result?.error) {\r\n\r\n if (result.code === 'rate_limit_error') {\r\n\r\n setIsLoading(true)\r\n setError('Too many failed login attempts. Please try again later.')\r\n return\r\n }\r\n\r\n else if (result.code === 'whitelist_invalid_credentials') {\r\n setError('Invalid email or password')\r\n setIsLoading(false)\r\n resetCaptcha()\r\n return\r\n }\r\n\r\n else if (!captchaStatus) {\r\n setError('Captcha Verification Failed.')\r\n setIsLoading(false)\r\n resetCaptcha()\r\n return\r\n }\r\n\r\n else if (result.code === 'invalid_credentials') {\r\n setError('Invalid email or password')\r\n setIsLoading(false)\r\n resetCaptcha()\r\n return\r\n }\r\n //MFA TRIGGER\r\n else if (result.code === 'mfa_required') {\r\n setStep('mfa')\r\n setIsLoading(false)\r\n return\r\n }\r\n\r\n else { //result.code === 'expired_recaptcha_token\r\n setError('Captcha Verification Expired. Please try again later.')\r\n setIsLoading(false)\r\n resetCaptcha()\r\n return\r\n }\r\n }\r\n\r\n // Completed Login + MFA - Redirect to the Platform's Organization Dashboard \r\n window.location.href = `/${orgName}`\r\n\r\n } catch (err) {\r\n setError('Unexpected error. Please try again.')\r\n setIsLoading(false)\r\n }\r\n }\r\n\r\n // VERIFY OTP for MFA\r\n const handleVerifyOTP = async () => {\r\n setIsLoading(true)\r\n setError('')\r\n\r\n try {\r\n const res = await fetch('/api/mfa', {\r\n method: 'POST',\r\n headers: { 'Content-Type': 'application/json' },\r\n body: JSON.stringify({ email, code }),\r\n })\r\n\r\n if (!res.ok) {\r\n toast.error(tMfa('invalidCode'))\r\n setIsLoading(false)\r\n return\r\n }\r\n\r\n toast.success(tMfa('success'))\r\n\r\n // FINAL LOGIN after successful MFA process\r\n await signIn('credentials', {\r\n email,\r\n password,\r\n mfaVerified: true,\r\n redirect: true,\r\n redirectTo: `/${orgName}`,\r\n })\r\n\r\n } catch (err) {\r\n toast.error(tMfa('verificationFailed'))\r\n setIsLoading(false)\r\n }\r\n }\r\n\r\n // Password Policy for New Password used for Reset Password flow\r\n const validatePassword = (password: string): string[] => {\r\n const errors: string[] = []\r\n\r\n // Regex Pattern - At least:\r\n // 1 lowercase:(?=.*[a-z])\r\n // 1 uppercase: (?=.*[A-Z])\r\n // 1 digit: (?=.*\\d)\r\n // 1 special char: (?=.*[@$!%*?&_])\r\n //min 12 characters, max 65: {12,65}\r\n const passwordRegex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[^a-zA-Z\\d\\s])[^\\s]{12,65}$/;\r\n if (!passwordRegex.test(password)) {\r\n errors.push(t('weakPassword'));\r\n }\r\n // if (password.toLowerCase().includes(username.toLowerCase())) {\r\n // //errors.push(t('containsUsername'));\r\n // errors.push(t('weakPassword'));\r\n\r\n // } \r\n\r\n return errors\r\n }\r\n\r\n const handlePasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => {\r\n const value = e.target.value\r\n setNewPassword(value)\r\n setNewPasswordErrors(validatePassword(value))\r\n if (confirmPassword) {\r\n setConfirmPasswordError(value === confirmPassword ? '' : tforgotPassword('noMatch'))\r\n }\r\n }\r\n const handleConfirmPasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => {\r\n const value = e.target.value\r\n setConfirmPassword(value)\r\n setConfirmPasswordError(value === newPassword ? '' : tforgotPassword('noMatch'))\r\n } \r\n\r\n //Forgot Password Flow: 1. User Clicks Reset Password > 2. OTP is emailed(forgotpassword API)\r\n // > 3. OTP is verified(verifyotp API) > 4. User chooses a new password(resetpassword API)\r\n\r\n //2. Initiate ForgotPasword flow - OTP is emailed\r\n const handleForgotPassword = async () => {\r\n setIsLoading(true)\r\n setError('')\r\n\r\n try {\r\n const res = await fetch('/api/forgotpassword', {\r\n method: 'POST',\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n body: JSON.stringify({\r\n email\r\n }),\r\n })\r\n\r\n if (!res.ok) {\r\n setError('Unable to send password reset email.')\r\n setIsLoading(false)\r\n return\r\n }\r\n\r\n //Redirect to Verify OTP flow to enter OTP that has been emailed \r\n setStep('forgotPasswordSent')\r\n setIsLoading(false)\r\n\r\n } catch {\r\n setError('Unable to process')\r\n setIsLoading(false)\r\n }\r\n}\r\n\r\n// 3. Handle Change Password - OTP is getting verified\r\n // VERIFY OTP for MFA\r\n const handleVerifyOTPForPasswordChange = async () => {\r\n //NEW------------------------------------------------------------------\r\n setIsLoading(true)\r\n setError('')\r\n\r\n try {\r\n\r\n const res = await fetch('/api/verifyotp', {\r\n\r\n method: 'POST',\r\n\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n\r\n body: JSON.stringify({\r\n email,\r\n code,\r\n }),\r\n })\r\n\r\n if (!res.ok) {\r\n\r\n //setError('Invalid verification code.')\r\n toast.error('Invalid verification code.')\r\n setIsLoading(false)\r\n return\r\n\r\n }\r\n toast.success(\"SUCCESS\")\r\n //Redirect User to enter New Password in Change Password page\r\n setStep('changePassword')\r\n\r\n } catch {\r\n\r\n setError('Unable to verify code.')\r\n\r\n } finally {\r\n\r\n setIsLoading(false)\r\n\r\n }\r\n\r\n }\r\n\r\n //Final Step: Reset Password \r\nconst handleResetPassword = async () => {\r\n\r\n setHasAttemptedSubmit(true)\r\n\r\n const errors = validatePassword(newPassword)\r\n\r\n setPasswordErrors(errors)\r\n \r\n\r\n if (newPassword !== confirmPassword) {\r\n\r\n toast.error(tforgotPassword('noMatch'))\r\n return\r\n\r\n }\r\n\r\n if (errors.length > 0){\r\n toast.error(tforgotPassword('passwordPolicyError'))\r\n return\r\n }\r\n setIsLoading(true)\r\n setError('')\r\n\r\n\r\n try {\r\n\r\n const res = await fetch('/api/resetpassword', {\r\n\r\n method: 'POST',\r\n\r\n headers: {\r\n 'Content-Type': 'application/json',\r\n },\r\n\r\n body: JSON.stringify({\r\n\r\n email,\r\n code,\r\n newPassword,\r\n\r\n }),\r\n })\r\n\r\n if (!res.ok) {\r\n\r\n toast.error('Session Expired: Unable to reset password.')\r\n setStep('login')\r\n return\r\n\r\n }\r\n\r\n toast.success('Password successfully changed.')\r\n\r\n setNewPassword('')\r\n setConfirmPassword('')\r\n setCode('')\r\n setStep('login')\r\n\r\n } finally {\r\n\r\n setIsLoading(false)\r\n\r\n }\r\n\r\n\r\n}\r\n return (\r\n <>\r\n <Toaster richColors position=\"top-right\" />\r\n\r\n {/* LOGIN FORM */}\r\n {step === 'login' && (\r\n <form onSubmit={handleSubmit} className=\"space-y-4\">\r\n {/* LOGIN Header */}\r\n <div className=\"space-y-2 text-left\">\r\n\r\n <h1 className=\"font-display font-bold\" style={{\r\n fontSize: '1.75rem',\r\n lineHeight: '1.1',\r\n letterSpacing: '-0.02em',\r\n color: 'var(--hp-on-surface)',\r\n }}>\r\n {/* {step === 'login' ? t('title') : tMfa('title')} */}\r\n {t('title')}\r\n </h1>\r\n\r\n <p style={{ color: 'var(--hp-on-surface-variant)', fontSize: '0.9rem' }}>\r\n {/* {step === 'login'\r\n ? t('message')\r\n : tMfa('subtitle', { email })} */}\r\n {t('message')}\r\n </p>\r\n </div> \r\n\r\n <Input\r\n type=\"email\"\r\n placeholder={t('placeholder1')}\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n disabled={isLoading}\r\n required\r\n />\r\n\r\n <div className=\"relative\">\r\n <Input\r\n type={showPassword ? 'text' : 'password'}\r\n placeholder={t('placeholder2')}\r\n value={password}\r\n onChange={(e) => setPassword(e.target.value)}\r\n disabled={isLoading}\r\n required\r\n className=\"pr-10\"\r\n />\r\n <button\r\n type=\"button\"\r\n onClick={() => setShowPassword(v => !v)}\r\n tabIndex={-1}\r\n className=\"absolute right-3 top-1/2 -translate-y-1/2 transition-colors\"\r\n style={{ color: 'var(--hp-on-surface-variant)' }}\r\n >\r\n {showPassword ? <LR.EyeOff size={16} /> : <LR.Eye size={16} />}\r\n </button>\r\n </div>\r\n {/* Google Not Linked Error */}\r\n {googleError === 'google_not_linked' && (\r\n <div className=\"auth-pw-error\">\r\n Your Google account is not linked. Please sign in with your credentials first, then link your Google account.\r\n </div>\r\n )}\r\n {error && <div className=\"auth-pw-error\">{error}</div>}\r\n\r\n <div className=\"flex items-center gap-2\">\r\n <Button type=\"submit\" disabled={isLoading} className=\"flex-1 auth-btn-primary\">\r\n {isLoading ? <LoadingSpinner /> : 'Login'}\r\n </Button>\r\n\r\n {/* Google button */}\r\n {<button\r\n type=\"button\"\r\n onClick={() => signIn('google', { redirectTo: `/${orgName}` })}\r\n disabled={isLoading}\r\n aria-label=\"Sign in with Google\"\r\n className=\"auth-google-btn\"\r\n >\r\n <GoogleIcon size={20} />\r\n </button>}\r\n\r\n </div>\r\n {/* Reset Password Link */}\r\n <button\r\n type=\"button\"\r\n onClick={() => {\r\n setError('')\r\n setStep('forgotPassword')\r\n }}\r\n className=\"text-sm underline underline-offset-4 hover:opacity-80\"\r\n style={{ color: 'var(--hp-primary)' }}\r\n >\r\n Reset your password\r\n </button>\r\n\r\n </form>\r\n )}\r\n\r\n {/* MFA FORM */}\r\n {step === 'mfa' && (\r\n <div className=\"space-y-4\">\r\n <div className=\"space-y-2 text-left\">\r\n <h1 className=\"font-display font-bold\" style={{\r\n fontSize: '1.75rem',\r\n lineHeight: '1.1',\r\n letterSpacing: '-0.02em',\r\n color: 'var(--hp-on-surface)',\r\n }}>\r\n {/* {step === 'login' ? t('title') : tMfa('title')} */}\r\n {tMfa('title')}\r\n </h1>\r\n\r\n <p style={{ color: 'var(--hp-on-surface-variant)', fontSize: '0.9rem' }}>\r\n {/* {step === 'login'\r\n ? t('message')\r\n : tMfa('subtitle', { email })} */}\r\n {tMfa('subtitle',{email})}\r\n </p>\r\n </div>\r\n\r\n <Input\r\n placeholder={tMfa('placeholder')}\r\n value={code}\r\n onChange={(e) => setCode(e.target.value)}\r\n disabled={isLoading}\r\n />\r\n\r\n <Button onClick={handleVerifyOTP} disabled={isLoading} className=\"w-full\">\r\n {isLoading ? <LoadingSpinner /> : tMfa('verify')}\r\n </Button>\r\n\r\n {/* Back */}\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => setStep('login')}\r\n className=\"w-full mt-3 inline-flex items-center justify-center gap-2\"\r\n >\r\n <LR.ArrowLeft size={16} />\r\n {tMfa('backToLogin')}\r\n </Button>\r\n </div>\r\n )}\r\n {/*Forgot Password step: Send OTP for Reset */}\r\n {step === 'forgotPassword' && (\r\n <div className=\"space-y-4\">\r\n <div className=\"space-y-2 text-left\">\r\n <h1 className=\"font-display font-bold\" style={{\r\n fontSize: '1.75rem',\r\n lineHeight: '1.1',\r\n letterSpacing: '-0.02em',\r\n color: 'var(--hp-on-surface)',\r\n }}>\r\n {/* {step === 'login' ? t('title') : tMfa('title')} */}\r\n {tresetPassword('title')}\r\n </h1>\r\n\r\n <p style={{ color: 'var(--hp-on-surface-variant)', fontSize: '0.9rem' }}>\r\n {/* {step === 'login'\r\n ? t('message')\r\n : tMfa('subtitle', { email })} */}\r\n {tresetPassword('subtitle')}\r\n </p>\r\n </div> \r\n\r\n <Input\r\n type=\"email\"\r\n placeholder=\"Enter your email address\"\r\n value={email}\r\n onChange={(e) => setEmail(e.target.value)}\r\n disabled={isLoading}\r\n />\r\n\r\n {error && (\r\n <div className=\"auth-pw-error\">\r\n {error}\r\n </div>\r\n )}\r\n\r\n <Button\r\n onClick={handleForgotPassword}\r\n disabled={isLoading || !email}\r\n className=\"w-full\"\r\n >\r\n {isLoading\r\n ? <LoadingSpinner />\r\n : 'Send Reset Link'}\r\n </Button>\r\n\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => setStep('login')}\r\n className=\"w-full\"\r\n >\r\n <LR.ArrowLeft size={16} />\r\n Back to Login\r\n </Button>\r\n\r\n </div>\r\n)}\r\n{/* Verify OTP for Password Change */}\r\n{step === 'forgotPasswordSent' && (\r\n <div className=\"space-y-4\">\r\n <div className=\"space-y-2 text-left\">\r\n <h1 className=\"font-display font-bold\" style={{\r\n fontSize: '1.75rem',\r\n lineHeight: '1.1',\r\n letterSpacing: '-0.02em',\r\n color: 'var(--hp-on-surface)',\r\n }}>\r\n {/* {step === 'login' ? t('title') : tMfa('title')} */}\r\n {tresetPassword('title')}\r\n </h1>\r\n\r\n <p style={{ color: 'var(--hp-on-surface-variant)', fontSize: '0.9rem' }}>\r\n {/* {step === 'login'\r\n ? t('message')\r\n : tMfa('subtitle', { email })} */}\r\n {tresetPassword('ifAnAccountExists',{email})}\r\n </p>\r\n </div>\r\n <Input\r\n placeholder={tMfa('placeholder')}\r\n value={code}\r\n onChange={(e) => setCode(e.target.value)}\r\n disabled={isLoading}\r\n />\r\n{error && (\r\n <div className=\"auth-pw-error\">\r\n {error}\r\n </div>\r\n)}\r\n <Button onClick={handleVerifyOTPForPasswordChange} disabled={isLoading} className=\"w-full\">\r\n {isLoading ? <LoadingSpinner /> : tMfa('verify')}\r\n </Button>\r\n\r\n <Button\r\n onClick={() => setStep('login')}\r\n className=\"w-full\"\r\n >\r\n Back to Login\r\n </Button>\r\n\r\n </div>\r\n)}\r\n\r\n{/*Change PAssword */}\r\n{step === 'changePassword' && (\r\n\r\n<div className=\"space-y-4\">\r\n <div className=\"space-y-2 text-left\">\r\n <h1 className=\"font-display font-bold\" style={{\r\n fontSize: '1.75rem',\r\n lineHeight: '1.1',\r\n letterSpacing: '-0.02em',\r\n color: 'var(--hp-on-surface)',\r\n }}>\r\n {/* {step === 'login' ? t('title') : tMfa('title')} */}\r\n {tresetPassword('newPasswordTitle')}\r\n </h1>\r\n\r\n <p style={{ color: 'var(--hp-on-surface-variant)', fontSize: '0.9rem' }}>\r\n {/* {step === 'login'\r\n ? t('message')\r\n : tMfa('subtitle', { email })} */}\r\n {tresetPassword('newPasswordMessage')}<br /> <br />\r\n {tresetPassword('lowercase')} <br />\r\n {tresetPassword('lowercase')} <br />\r\n {tresetPassword('uppercase')} <br />\r\n {tresetPassword('digit')} <br />\r\n {tresetPassword('specialchar')} <br />\r\n {tresetPassword('minmax')} <br />\r\n </p>\r\n\r\n </div>\r\n \r\n \r\n <Input\r\n type={showNewPassword ? 'text' : 'password'}\r\n placeholder=\"New Password\"\r\n className={`w-full ${hasAttemptedSave && newPasswordErrors.length > 0 ? 'border-destructive' : ''}`}\r\n value={newPassword}\r\n onChange={handlePasswordChange}\r\n />\r\n\r\n {hasAttemptedSave && newPasswordErrors.map((error, idx) => (\r\n <PasswordError key={idx} message={error} />\r\n ))}\r\n\r\n\r\n <Input\r\n type={showConfirmPassword ? 'text' : 'password'}\r\n placeholder=\"Confirm Password\"\r\n value={confirmPassword}\r\n onChange={handleConfirmPasswordChange}\r\n />\r\n\r\n \r\n {hasAttemptedSave && confirmPasswordError && (\r\n <PasswordError message={confirmPasswordError} />\r\n )}\r\n\r\n {error && (\r\n <div className=\"auth-pw-error\">\r\n {error}\r\n </div>\r\n )}\r\n\r\n <Button\r\n onClick={handleResetPassword}\r\n disabled={isLoading}\r\n className=\"w-full\"\r\n >\r\n {isLoading\r\n ? <LoadingSpinner />\r\n : 'Change Password'}\r\n </Button>\r\n\r\n\r\n <Button\r\n variant=\"outline\"\r\n onClick={() => setStep('login')}\r\n className=\"w-full\"\r\n >\r\n <LR.ArrowLeft size={16} />\r\n Back to Login\r\n </Button>\r\n\r\n</div>\r\n\r\n)}\r\n {/* CAPTCHA only on Credentials(Username and Password) Provider login */}\r\n \r\n {step === 'login' && (\r\n <div className=\"auth-captcha-wrapper\">\r\n <ReCAPTCHA\r\n ref={recaptchaRef}\r\n key={`recaptcha-${authTheme}`}\r\n sitekey={recaptchaSiteKey ?? ''}\r\n onChange={(token) => onReCaptchaSuccess(token)}\r\n theme={authTheme}\r\n />\r\n </div>\r\n )}\r\n </>\r\n )\r\n}\r\n\r\ninterface SignInProps {\r\n recaptchaSiteKey?: string\r\n minioBaseUrl?: string\r\n}\r\n\r\nexport function SignIn({ recaptchaSiteKey,minioBaseUrl, }: SignInProps) {\r\n return (\r\n <AuthPage minioBaseUrl={minioBaseUrl}>\r\n <SignInContent recaptchaSiteKey={recaptchaSiteKey} />\r\n </AuthPage>\r\n )\r\n}"],"mappings":"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","names":["_a","password","error"]}
@@ -14,10 +14,10 @@ function UserSettings({ minioBaseUrl }) {
14
14
  { key: "users", label: t("users") },
15
15
  { key: "organization", label: t("organization") }
16
16
  ], [t]);
17
- return /* @__PURE__ */ jsx("div", { className: "sm:p-2 overflow-hidden bg-[#fafafa] h-full", children: /* @__PURE__ */ jsx("div", { className: "bg-background rounded-xl shadow min-h-full", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-screen", children: [
17
+ return /* @__PURE__ */ jsx("div", { className: "sm:p-2 overflow-hidden bg-[#fafafa] h-full", children: /* @__PURE__ */ jsx("div", { className: "bg-background rounded-xl shadow min-h-full", children: /* @__PURE__ */ jsxs("div", { className: "flex flex-col h-full", children: [
18
18
  /* @__PURE__ */ jsx(SettingsHeader, { title: t("settings") }),
19
- /* @__PURE__ */ jsxs("div", { className: "flex flex-row gap-2 p-6 h-full overflow-hidden", children: [
20
- /* @__PURE__ */ jsx("div", { className: "hidden md:!flex flex-shrink-0 pr-4 lg:w-[280px]", children: /* @__PURE__ */ jsx(
19
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col md:flex-row gap-2 p-6 flex-1 min-h-0 overflow-y-auto md:overflow-hidden", children: [
20
+ /* @__PURE__ */ jsx("div", { className: "flex-shrink-0 md:pr-4 lg:w-[280px]", children: /* @__PURE__ */ jsx(
21
21
  SettingsSidebar,
22
22
  {
23
23
  tabs,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/core/components/settings/index.tsx"],"sourcesContent":["\"use client\"\r\n\r\n// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as React from 'react'\r\nimport { useTranslations } from 'next-intl'\r\n\r\nimport { Separator } from '../ui/'\r\n\r\nimport SettingsHeader from './src/SettingsHeader'\r\nimport SettingsSidebar from './src/SettingsSidebar'\r\nimport SettingsContent from './src/SettingsContent'\r\nimport type { SettingsTabKey } from './src/types'\r\n\r\nexport function UserSettings({ minioBaseUrl }: { minioBaseUrl?: string }) {\r\n const t = useTranslations('UserSettings')\r\n const [activeTab, setActiveTab] = React.useState<SettingsTabKey>('account')\r\n\r\n const tabs = React.useMemo(() => (\r\n [\r\n { key: 'account' as const, label: t('account') },\r\n { key: 'users' as const, label: t('users') },\r\n { key: 'organization' as const, label: t('organization') },\r\n ]\r\n ), [t])\r\n\r\n return (\r\n <div className=\"sm:p-2 overflow-hidden bg-[#fafafa] h-full\">\r\n <div className=\"bg-background rounded-xl shadow min-h-full\">\r\n <div className=\"flex flex-col h-screen\">\r\n <SettingsHeader title={t('settings')} />\r\n\r\n <div className=\"flex flex-row gap-2 p-6 h-full overflow-hidden\">\r\n <div className=\"hidden md:!flex flex-shrink-0 pr-4 lg:w-[280px]\">\r\n <SettingsSidebar\r\n tabs={tabs}\r\n activeTab={activeTab}\r\n onTabChange={setActiveTab}\r\n />\r\n </div>\r\n\r\n <Separator orientation=\"vertical\" className=\"hidden md:!flex\" />\r\n\r\n <SettingsContent activeTab={activeTab} minioBaseUrl={minioBaseUrl} />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )\r\n}\r\n"],"mappings":";AA+BU,cAEA,YAFA;AA1BV,YAAY,WAAW;AACvB,SAAS,uBAAuB;AAEhC,SAAS,iBAAiB;AAE1B,OAAO,oBAAoB;AAC3B,OAAO,qBAAqB;AAC5B,OAAO,qBAAqB;AAGrB,SAAS,aAAa,EAAE,aAAa,GAA8B;AACxE,QAAM,IAAI,gBAAgB,cAAc;AACxC,QAAM,CAAC,WAAW,YAAY,IAAI,MAAM,SAAyB,SAAS;AAE1E,QAAM,OAAO,MAAM,QAAQ,MACzB;AAAA,IACE,EAAE,KAAK,WAAoB,OAAO,EAAE,SAAS,EAAE;AAAA,IAC/C,EAAE,KAAK,SAAkB,OAAO,EAAE,OAAO,EAAE;AAAA,IAC3C,EAAE,KAAK,gBAAyB,OAAO,EAAE,cAAc,EAAE;AAAA,EAC3D,GACC,CAAC,CAAC,CAAC;AAEN,SACE,oBAAC,SAAI,WAAU,8CACb,8BAAC,SAAI,WAAU,8CACb,+BAAC,SAAI,WAAU,0BACb;AAAA,wBAAC,kBAAe,OAAO,EAAE,UAAU,GAAG;AAAA,IAEtC,qBAAC,SAAI,WAAU,kDACb;AAAA,0BAAC,SAAI,WAAU,mDACb;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA,aAAa;AAAA;AAAA,MACf,GACF;AAAA,MAEA,oBAAC,aAAU,aAAY,YAAW,WAAU,mBAAkB;AAAA,MAE9D,oBAAC,mBAAgB,WAAsB,cAA4B;AAAA,OACrE;AAAA,KACF,GACF,GACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../../src/core/components/settings/index.tsx"],"sourcesContent":["\"use client\"\r\n\r\n// SPDX-License-Identifier: AGPL-3.0-or-later\r\n// Copyright (C) 2025 Collab Digital Twins\r\n\r\nimport * as React from 'react'\r\nimport { useTranslations } from 'next-intl'\r\n\r\nimport { Separator } from '../ui/'\r\n\r\nimport SettingsHeader from './src/SettingsHeader'\r\nimport SettingsSidebar from './src/SettingsSidebar'\r\nimport SettingsContent from './src/SettingsContent'\r\nimport type { SettingsTabKey } from './src/types'\r\n\r\nexport function UserSettings({ minioBaseUrl }: { minioBaseUrl?: string }) {\r\n const t = useTranslations('UserSettings')\r\n const [activeTab, setActiveTab] = React.useState<SettingsTabKey>('account')\r\n\r\n const tabs = React.useMemo(() => (\r\n [\r\n { key: 'account' as const, label: t('account') },\r\n { key: 'users' as const, label: t('users') },\r\n { key: 'organization' as const, label: t('organization') },\r\n ]\r\n ), [t])\r\n\r\n return (\r\n <div className=\"sm:p-2 overflow-hidden bg-[#fafafa] h-full\">\r\n <div className=\"bg-background rounded-xl shadow min-h-full\">\r\n <div className=\"flex flex-col h-full\">\r\n <SettingsHeader title={t('settings')} />\r\n\r\n <div className=\"flex flex-col md:flex-row gap-2 p-6 flex-1 min-h-0 overflow-y-auto md:overflow-hidden\">\r\n <div className=\"flex-shrink-0 md:pr-4 lg:w-[280px]\">\r\n <SettingsSidebar\r\n tabs={tabs}\r\n activeTab={activeTab}\r\n onTabChange={setActiveTab}\r\n />\r\n </div>\r\n\r\n <Separator orientation=\"vertical\" className=\"hidden md:!flex\" />\r\n\r\n <SettingsContent activeTab={activeTab} minioBaseUrl={minioBaseUrl} />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n )\r\n}\r\n"],"mappings":";AA+BU,cAEA,YAFA;AA1BV,YAAY,WAAW;AACvB,SAAS,uBAAuB;AAEhC,SAAS,iBAAiB;AAE1B,OAAO,oBAAoB;AAC3B,OAAO,qBAAqB;AAC5B,OAAO,qBAAqB;AAGrB,SAAS,aAAa,EAAE,aAAa,GAA8B;AACxE,QAAM,IAAI,gBAAgB,cAAc;AACxC,QAAM,CAAC,WAAW,YAAY,IAAI,MAAM,SAAyB,SAAS;AAE1E,QAAM,OAAO,MAAM,QAAQ,MACzB;AAAA,IACE,EAAE,KAAK,WAAoB,OAAO,EAAE,SAAS,EAAE;AAAA,IAC/C,EAAE,KAAK,SAAkB,OAAO,EAAE,OAAO,EAAE;AAAA,IAC3C,EAAE,KAAK,gBAAyB,OAAO,EAAE,cAAc,EAAE;AAAA,EAC3D,GACC,CAAC,CAAC,CAAC;AAEN,SACE,oBAAC,SAAI,WAAU,8CACb,8BAAC,SAAI,WAAU,8CACb,+BAAC,SAAI,WAAU,wBACb;AAAA,wBAAC,kBAAe,OAAO,EAAE,UAAU,GAAG;AAAA,IAEtC,qBAAC,SAAI,WAAU,yFACb;AAAA,0BAAC,SAAI,WAAU,sCACb;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA,aAAa;AAAA;AAAA,MACf,GACF;AAAA,MAEA,oBAAC,aAAU,aAAY,YAAW,WAAU,mBAAkB;AAAA,MAE9D,oBAAC,mBAAgB,WAAsB,cAA4B;AAAA,OACrE;AAAA,KACF,GACF,GACF;AAEJ;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"OrganizationSettingsPanel.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/settings/src/OrganizationSettingsPanel.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AA0B9B,UAAU,8BAA8B;IACtC,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAAC,EAChD,YAAY,GACb,EAAE,8BAA8B,qBA+chC"}
1
+ {"version":3,"file":"OrganizationSettingsPanel.d.ts","sourceRoot":"","sources":["../../../../../src/core/components/settings/src/OrganizationSettingsPanel.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AA0B9B,UAAU,8BAA8B;IACtC,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAAC,EAChD,YAAY,GACb,EAAE,8BAA8B,qBAgdhC"}
@@ -290,11 +290,12 @@ function OrganizationSettingsPanel({
290
290
  /* @__PURE__ */ jsx(
291
291
  Input,
292
292
  {
293
- value: getFieldValue("name") || "",
294
- onChange: (e) => handleInputChange("name", e.target.value),
295
- disabled: !isEditing || !ability.can("update", "Organization")
293
+ value: (organization == null ? void 0 : organization.name) || "",
294
+ disabled: true,
295
+ readOnly: true
296
296
  }
297
- )
297
+ ),
298
+ /* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: t("fields.nameLocked") })
298
299
  ] }),
299
300
  /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
300
301
  /* @__PURE__ */ jsx("label", { className: "text-sm font-medium", children: t("fields.title") }),