@harperfast/harper-pro 5.0.0-beta.1 → 5.0.0-beta.2
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/core/.github/workflows/integration-tests.yml +7 -5
- package/core/components/componentLoader.ts +1 -1
- package/core/integrationTests/utils/harperLifecycle.ts +9 -5
- package/core/package.json +2 -1
- package/core/resources/ResourceInterface.ts +1 -1
- package/core/resources/Table.ts +9 -5
- package/core/resources/search.ts +1 -1
- package/core/security/jsLoader.ts +23 -6
- package/core/security/keys.js +7 -7
- package/core/unitTests/components/fixtures/testJSWithDeps/child-dir/typestrip.ts +2 -0
- package/core/unitTests/components/fixtures/testJSWithDeps/resources.js +3 -0
- package/core/unitTests/components/globalIsolation.test.js +1 -0
- package/core/unitTests/resources/query.test.js +16 -1
- package/core/utility/lmdb/commonUtility.js +21 -10
- package/dist/cloneNode/cloneNode.js +7 -3
- package/dist/cloneNode/cloneNode.js.map +1 -1
- package/dist/core/components/componentLoader.js +1 -1
- package/dist/core/components/componentLoader.js.map +1 -1
- package/dist/core/resources/Table.js +8 -3
- package/dist/core/resources/Table.js.map +1 -1
- package/dist/core/resources/search.js +1 -1
- package/dist/core/resources/search.js.map +1 -1
- package/dist/core/security/jsLoader.js +22 -7
- package/dist/core/security/jsLoader.js.map +1 -1
- package/dist/core/security/keys.js +7 -7
- package/dist/core/security/keys.js.map +1 -1
- package/dist/core/utility/lmdb/commonUtility.js +20 -13
- package/dist/core/utility/lmdb/commonUtility.js.map +1 -1
- package/dist/licensing/usageLicensing.js.map +1 -1
- package/dist/replication/knownNodes.js +5 -37
- package/dist/replication/knownNodes.js.map +1 -1
- package/dist/replication/nodeIdMapping.js +2 -35
- package/dist/replication/nodeIdMapping.js.map +1 -1
- package/dist/replication/replicationConnection.js +6 -3
- package/dist/replication/replicationConnection.js.map +1 -1
- package/dist/replication/replicator.js +3 -2
- package/dist/replication/replicator.js.map +1 -1
- package/dist/replication/setNode.js +1 -1
- package/dist/replication/setNode.js.map +1 -1
- package/dist/security/certificate.js.map +1 -1
- package/licensing/usageLicensing.ts +3 -2
- package/npm-shrinkwrap.json +59 -48
- package/package.json +3 -2
- package/replication/knownNodes.ts +3 -2
- package/replication/nodeIdMapping.ts +1 -1
- package/replication/replicationConnection.ts +17 -5
- package/replication/replicator.ts +7 -2
- package/replication/setNode.ts +1 -1
- package/security/certificate.ts +2 -1
- package/studio/web/assets/{index-PFlNdimM.js → index-CWN9Wp5V.js} +2 -2
- package/studio/web/assets/{index-PFlNdimM.js.map → index-CWN9Wp5V.js.map} +1 -1
- package/studio/web/assets/{index-C-GXfcup.js → index-CzghSAn2.js} +2 -2
- package/studio/web/assets/{index-C-GXfcup.js.map → index-CzghSAn2.js.map} +1 -1
- package/studio/web/assets/{index-BTgXJX9d.js → index-DMDhGP7N.js} +5 -5
- package/studio/web/assets/{index-BTgXJX9d.js.map → index-DMDhGP7N.js.map} +1 -1
- package/studio/web/assets/{index.lazy-C3TJZJ4o.js → index.lazy-C-yDTGUy.js} +2 -2
- package/studio/web/assets/{index.lazy-C3TJZJ4o.js.map → index.lazy-C-yDTGUy.js.map} +1 -1
- package/studio/web/assets/{profiler-DotzgiCJ.js → profiler-0fZAOscv.js} +2 -2
- package/studio/web/assets/{profiler-DotzgiCJ.js.map → profiler-0fZAOscv.js.map} +1 -1
- package/studio/web/assets/{react-redux-VxUEx_mU.js → react-redux-BIxqK8O6.js} +2 -2
- package/studio/web/assets/{react-redux-VxUEx_mU.js.map → react-redux-BIxqK8O6.js.map} +1 -1
- package/studio/web/assets/{startRecording-B_9J9Csd.js → startRecording-Ca3Gf2MY.js} +2 -2
- package/studio/web/assets/{startRecording-B_9J9Csd.js.map → startRecording-Ca3Gf2MY.js.map} +1 -1
- package/studio/web/index.html +1 -1
- package/core/resources/ResourceInterfaceV2.ts +0 -53
- package/core/resources/ResourceV2.ts +0 -67
- package/core/v1.d.ts +0 -39
- package/core/v1.js +0 -41
- package/core/v2.d.ts +0 -39
- package/core/v2.js +0 -41
- package/dist/core/resources/ResourceInterfaceV2.js +0 -3
- package/dist/core/resources/ResourceInterfaceV2.js.map +0 -1
- package/dist/core/resources/ResourceV2.js +0 -27
- package/dist/core/resources/ResourceV2.js.map +0 -1
|
@@ -150,7 +150,11 @@ export function start(options) {
|
|
|
150
150
|
} else {
|
|
151
151
|
logger.error(
|
|
152
152
|
`Incoming client connection from ${request.peerCertificate?.subjectaltname ?? request.ip} did not have valid certificate, you may need turn on enableRootCAs in the config if you are using a publicly signed certificate, or add the CA to the server's trusted CAs`,
|
|
153
|
-
authorizationError
|
|
153
|
+
authorizationError,
|
|
154
|
+
'certificate issuer',
|
|
155
|
+
request.peerCertificate.issuer,
|
|
156
|
+
'did not match any available CAs',
|
|
157
|
+
Array.from(Array.from(wsServers[0].secureContexts.values())[0].options.availableCAs.keys())
|
|
154
158
|
);
|
|
155
159
|
}
|
|
156
160
|
}
|
|
@@ -265,6 +269,7 @@ export function start(options) {
|
|
|
265
269
|
export function monitorNodeCAs(listener: () => void) {
|
|
266
270
|
let lastCaCount = 0;
|
|
267
271
|
subscribeToNodeUpdates((node) => {
|
|
272
|
+
logger.debug('Adding node CA', node?.ca?.slice(0, 60));
|
|
268
273
|
if (node?.ca) {
|
|
269
274
|
// we only care about nodes that have a CA
|
|
270
275
|
replicationCertificateAuthorities.add(node.ca);
|
|
@@ -639,7 +644,7 @@ export function lastTimeInAuditStore(auditStore: Database) {
|
|
|
639
644
|
|
|
640
645
|
export async function replicateOperation(req) {
|
|
641
646
|
const response = { message: '' };
|
|
642
|
-
if (req.replicated) {
|
|
647
|
+
if (req.replicated !== false) {
|
|
643
648
|
req.replicated = false; // don't send a replicated flag to the nodes we are sending to
|
|
644
649
|
logger.trace?.(
|
|
645
650
|
'Replicating operation',
|
package/replication/setNode.ts
CHANGED
|
@@ -153,7 +153,7 @@ export async function setNode(req: any) {
|
|
|
153
153
|
if (targetNodeResponse.certificate) {
|
|
154
154
|
await setCertTable({
|
|
155
155
|
name: getThisNodeName(),
|
|
156
|
-
uses: ['https', 'operations', 'wss'],
|
|
156
|
+
uses: ['https', 'operations', 'wss', 'replication'],
|
|
157
157
|
certificate: targetNodeResponse.certificate,
|
|
158
158
|
private_key_name: rep?.options?.key_file,
|
|
159
159
|
is_authority: false,
|
package/security/certificate.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { Logger } from '../core/utility/logging/logger.ts';
|
|
1
2
|
import Joi from 'joi';
|
|
2
3
|
import forge from 'node-forge';
|
|
3
4
|
import { access, constants, readFile, writeFile, unlink } from 'node:fs/promises';
|
|
@@ -25,7 +26,7 @@ import { server } from '../core/server/Server.ts';
|
|
|
25
26
|
import { replicateOperation } from '../replication/replicator.ts';
|
|
26
27
|
|
|
27
28
|
const { forComponent } = harperLogger;
|
|
28
|
-
const logger = forComponent('certificate').conditional;
|
|
29
|
+
const logger = forComponent('certificate').conditional as Logger;
|
|
29
30
|
const pki = forge.pki;
|
|
30
31
|
const CERT_VALIDITY_DAYS = 3650;
|
|
31
32
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{$ as useMutation,a0 as apiClient,a1 as object,a2 as string,a3 as useRouter,a4 as useNavigate,a5 as useCloudAuth,a6 as useForm,a7 as a,a8 as reactExports,a9 as authStore,aa as OverallAppSignIn,ab as toast,ac as logoutOnSuccess,ad as jsxRuntimeExports,ae as Form,af as FormField,ag as FormItem,ah as FormLabel,ai as FormControl,aj as Input,ak as FormMessage,al as Button,am as Save}from"./index-
|
|
2
|
-
//# sourceMappingURL=index-
|
|
1
|
+
var __defProp=Object.defineProperty;var __name=(target,value)=>__defProp(target,"name",{value,configurable:!0});import{$ as useMutation,a0 as apiClient,a1 as object,a2 as string,a3 as useRouter,a4 as useNavigate,a5 as useCloudAuth,a6 as useForm,a7 as a,a8 as reactExports,a9 as authStore,aa as OverallAppSignIn,ab as toast,ac as logoutOnSuccess,ad as jsxRuntimeExports,ae as Form,af as FormField,ag as FormItem,ah as FormLabel,ai as FormControl,aj as Input,ak as FormMessage,al as Button,am as Save}from"./index-DMDhGP7N.js";async function onUpdateUser(formData){const{id,newPassword,confirmNewPassword,...otherFields}=formData,userData={...otherFields};newPassword&&newPassword===confirmNewPassword&&(userData.password=newPassword);const{data}=await apiClient.patch(`/User/${id}`,userData);return data}__name(onUpdateUser,"onUpdateUser");function useUpdateUserMutation(){return useMutation({mutationFn:__name(formData=>onUpdateUser(formData),"mutationFn")})}__name(useUpdateUserMutation,"useUpdateUserMutation");const UpdateUserSchema=object({id:string(),firstname:string({error:"Please enter your first name."}).min(2,{error:"First name is required."}).max(50,{error:"First name must be less than 50 characters."}),lastname:string({error:"Please enter your last name."}).min(2,{error:"Last name is required."}).max(50,{error:"Last name must be less than 50 characters."}),newPassword:string({error:"Please enter your new password."}).min(8,{error:"Password must be 8 characters or more."}).or(string().max(0)),confirmNewPassword:string().optional()}).refine(data=>data.newPassword===data.confirmNewPassword,{error:"Passwords do not match",path:["confirmNewPassword"]});function ProfileIndex(){const router=useRouter(),navigate=useNavigate(),{user}=useCloudAuth(),methods=useForm({resolver:a(UpdateUserSchema),defaultValues:{confirmNewPassword:"",firstname:user?.firstname||"",id:user?.id||"",lastname:user?.lastname||"",newPassword:""}}),{control,handleSubmit,reset,formState:{defaultValues,isDirty,isValid}}=methods,{mutate:updateUser,isPending:isUpdatePending}=useUpdateUserMutation(),onSubmitClick=reactExports.useCallback(async formData=>{formData&&updateUser(formData,{onSuccess:__name(data=>{reset({...defaultValues,...data}),authStore.updateUserForEntity(OverallAppSignIn,data),formData.newPassword?(toast.success("Profile updated successfully!",{description:"Please sign in with your new password."}),logoutOnSuccess(),navigate({to:"/sign-in"}),router.invalidate()):toast.success("Profile updated successfully!")},"onSuccess")})},[defaultValues,navigate,reset,router,updateUser]);return jsxRuntimeExports.jsxs("div",{className:"mt-20 px-4 pt-4 md:px-12",children:[jsxRuntimeExports.jsx("h2",{className:"text-2xl font-light",children:"Profile"}),jsxRuntimeExports.jsx(Form,{...methods,children:jsxRuntimeExports.jsxs("form",{id:"profile-edit-form",name:"profile-edit-form",onSubmit:handleSubmit(onSubmitClick),className:"grid gap-4 my-4",children:[jsxRuntimeExports.jsx(FormField,{control,name:"firstname",render:__name(({field})=>jsxRuntimeExports.jsxs(FormItem,{children:[jsxRuntimeExports.jsx(FormLabel,{className:"pb-1",children:"First Name"}),jsxRuntimeExports.jsx(FormControl,{children:jsxRuntimeExports.jsx(Input,{type:"text",className:"bg-purple-400 border-purple-400 dark:bg-black dark:border-black",autoCapitalize:"words",...field})}),jsxRuntimeExports.jsx(FormMessage,{})]}),"render")}),jsxRuntimeExports.jsx(FormField,{control,name:"lastname",render:__name(({field})=>jsxRuntimeExports.jsxs(FormItem,{children:[jsxRuntimeExports.jsx(FormLabel,{className:"pb-1",children:"Last Name"}),jsxRuntimeExports.jsx(FormControl,{children:jsxRuntimeExports.jsx(Input,{type:"text",className:"bg-purple-400 border-purple-400 dark:bg-black dark:border-black",autoCapitalize:"words",...field})}),jsxRuntimeExports.jsx(FormMessage,{})]}),"render")}),jsxRuntimeExports.jsx(FormLabel,{className:"pb-1",children:"Email"}),jsxRuntimeExports.jsx(FormControl,{children:jsxRuntimeExports.jsx(Input,{type:"email",enterKeyHint:"next",autoComplete:"email",autoCapitalize:"none",value:user?.email||"",disabled:!0,readOnly:!0})}),jsxRuntimeExports.jsx(FormField,{control,name:"newPassword",render:__name(({field})=>jsxRuntimeExports.jsxs(FormItem,{children:[jsxRuntimeExports.jsx(FormLabel,{className:"pb-1",children:"New Password"}),jsxRuntimeExports.jsx(FormControl,{children:jsxRuntimeExports.jsx(Input,{type:"password",placeholder:"Optional",className:"bg-purple-400 border-purple-400 dark:bg-black dark:border-black",autoComplete:"new-password",autoCapitalize:"none",...field})}),jsxRuntimeExports.jsx(FormMessage,{})]}),"render")}),jsxRuntimeExports.jsx(FormField,{control,name:"confirmNewPassword",render:__name(({field})=>jsxRuntimeExports.jsxs(FormItem,{children:[jsxRuntimeExports.jsx(FormLabel,{className:"pb-1",children:"Confirm New Password"}),jsxRuntimeExports.jsx(FormControl,{children:jsxRuntimeExports.jsx(Input,{type:"password",className:"bg-purple-400 border-purple-400 dark:bg-black dark:border-black",autoComplete:"new-password",autoCapitalize:"none",...field})}),jsxRuntimeExports.jsx(FormMessage,{})]}),"render")}),jsxRuntimeExports.jsx("div",{className:"flex justify-between w-full",children:jsxRuntimeExports.jsxs(Button,{type:"submit",variant:"submit",className:"rounded-full",disabled:isUpdatePending||!isDirty||!isValid,children:[jsxRuntimeExports.jsx(Save,{})," Update Profile"]})})]})})]})}__name(ProfileIndex,"ProfileIndex");export{ProfileIndex};
|
|
2
|
+
//# sourceMappingURL=index-CWN9Wp5V.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-PFlNdimM.js","sources":["../../src/features/profile/mutations/updateUserMutation.ts","../../src/features/profile/mutations/updateUserSchema.ts","../../src/features/profile/index.tsx"],"sourcesContent":["import { apiClient } from '@/config/apiClient';\nimport { UpdateUserSchema } from '@/features/profile/mutations/updateUserSchema';\nimport { SchemaUser } from '@/integrations/api/api.gen';\nimport { User } from '@/integrations/api/api.patch';\nimport { useMutation } from '@tanstack/react-query';\nimport z from 'zod';\n\nasync function onUpdateUser(formData: z.infer<typeof UpdateUserSchema>) {\n\tconst { id, newPassword, confirmNewPassword, ...otherFields } = formData;\n\tconst userData: Partial<SchemaUser & { password: string }> = {\n\t\t...otherFields,\n\t};\n\tif (newPassword && newPassword === confirmNewPassword) {\n\t\tuserData.password = newPassword;\n\t}\n\tconst { data } = await apiClient.patch(`/User/${id}` as '/User/{id}', userData);\n\treturn data as Partial<User>;\n}\n\nexport function useUpdateUserMutation() {\n\treturn useMutation({\n\t\tmutationFn: (formData: z.infer<typeof UpdateUserSchema>) => onUpdateUser(formData),\n\t});\n}\n","import { z } from 'zod';\n\nexport const UpdateUserSchema = z\n\t.object({\n\t\tid: z.string(),\n\t\tfirstname: z\n\t\t\t.string({\n\t\t\t\terror: 'Please enter your first name.',\n\t\t\t})\n\t\t\t.min(2, { error: 'First name is required.' })\n\t\t\t.max(50, { error: 'First name must be less than 50 characters.' }),\n\t\tlastname: z\n\t\t\t.string({\n\t\t\t\terror: 'Please enter your last name.',\n\t\t\t})\n\t\t\t.min(2, { error: 'Last name is required.' })\n\t\t\t.max(50, { error: 'Last name must be less than 50 characters.' }),\n\t\tnewPassword: z\n\t\t\t.string({\n\t\t\t\terror: 'Please enter your new password.',\n\t\t\t})\n\t\t\t.min(8, { error: 'Password must be 8 characters or more.' })\n\t\t\t.or(z.string().max(0)),\n\t\tconfirmNewPassword: z\n\t\t\t.string()\n\t\t\t.optional(),\n\t})\n\t.refine((data) => data.newPassword === data.confirmNewPassword, {\n\t\terror: 'Passwords do not match',\n\t\tpath: ['confirmNewPassword'],\n\t});\n","import { Button } from '@/components/ui/button';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { logoutOnSuccess } from '@/features/auth/handlers/logoutOnSuccess';\nimport { authStore, OverallAppSignIn } from '@/features/auth/store/authStore';\nimport { useUpdateUserMutation } from '@/features/profile/mutations/updateUserMutation';\nimport { UpdateUserSchema } from '@/features/profile/mutations/updateUserSchema';\nimport { useCloudAuth } from '@/hooks/useAuth';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useNavigate, useRouter } from '@tanstack/react-router';\nimport { Save } from 'lucide-react';\nimport { useCallback } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\n\nexport function ProfileIndex() {\n\tconst router = useRouter();\n\tconst navigate = useNavigate();\n\tconst { user } = useCloudAuth();\n\n\tconst methods = useForm({\n\t\tresolver: zodResolver(UpdateUserSchema),\n\t\tdefaultValues: {\n\t\t\tconfirmNewPassword: '',\n\t\t\tfirstname: user?.firstname || '',\n\t\t\tid: user?.id || '',\n\t\t\tlastname: user?.lastname || '',\n\t\t\tnewPassword: '',\n\t\t},\n\t});\n\tconst { control, handleSubmit, reset, formState: { defaultValues, isDirty, isValid } } = methods;\n\tconst { mutate: updateUser, isPending: isUpdatePending } = useUpdateUserMutation();\n\n\tconst onSubmitClick = useCallback(\n\t\tasync (formData: z.infer<typeof UpdateUserSchema>) => {\n\t\t\tif (formData) {\n\t\t\t\tupdateUser(formData, {\n\t\t\t\t\tonSuccess: (data) => {\n\t\t\t\t\t\treset({\n\t\t\t\t\t\t\t...defaultValues,\n\t\t\t\t\t\t\t...data,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tauthStore.updateUserForEntity(OverallAppSignIn, data);\n\t\t\t\t\t\tif (formData.newPassword) {\n\t\t\t\t\t\t\ttoast.success('Profile updated successfully!', {\n\t\t\t\t\t\t\t\tdescription: 'Please sign in with your new password.',\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tlogoutOnSuccess();\n\t\t\t\t\t\t\tvoid navigate({ to: '/sign-in' });\n\t\t\t\t\t\t\tvoid router.invalidate();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttoast.success('Profile updated successfully!');\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[defaultValues, navigate, reset, router, updateUser],\n\t);\n\n\treturn (\n\t\t<div className=\"mt-20 px-4 pt-4 md:px-12\">\n\t\t\t<h2 className=\"text-2xl font-light\">Profile</h2>\n\t\t\t<Form {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tid=\"profile-edit-form\"\n\t\t\t\t\tname=\"profile-edit-form\"\n\t\t\t\t\tonSubmit={handleSubmit(onSubmitClick)}\n\t\t\t\t\tclassName=\"grid gap-4 my-4\"\n\t\t\t\t>\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"firstname\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">First Name</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"bg-purple-400 border-purple-400 dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"words\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"lastname\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Last Name</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"bg-purple-400 border-purple-400 dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"words\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<FormLabel className=\"pb-1\">Email</FormLabel>\n\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\t\tenterKeyHint=\"next\"\n\t\t\t\t\t\t\tautoComplete=\"email\"\n\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\tvalue={user?.email || ''}\n\t\t\t\t\t\t\tdisabled={true}\n\t\t\t\t\t\t\treadOnly={true}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</FormControl>\n\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"newPassword\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">New Password</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\t\tplaceholder=\"Optional\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"bg-purple-400 border-purple-400 dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"confirmNewPassword\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Confirm New Password</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"bg-purple-400 border-purple-400 dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<div className=\"flex justify-between w-full\">\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\tdisabled={isUpdatePending || !isDirty || !isValid}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Save /> Update Profile\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t</form>\n\t\t\t</Form>\n\t\t</div>\n\t);\n}\n"],"names":["z.object","z.string","zodResolver","useCallback","jsxs","jsx"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index-CWN9Wp5V.js","sources":["../../src/features/profile/mutations/updateUserMutation.ts","../../src/features/profile/mutations/updateUserSchema.ts","../../src/features/profile/index.tsx"],"sourcesContent":["import { apiClient } from '@/config/apiClient';\nimport { UpdateUserSchema } from '@/features/profile/mutations/updateUserSchema';\nimport { SchemaUser } from '@/integrations/api/api.gen';\nimport { User } from '@/integrations/api/api.patch';\nimport { useMutation } from '@tanstack/react-query';\nimport z from 'zod';\n\nasync function onUpdateUser(formData: z.infer<typeof UpdateUserSchema>) {\n\tconst { id, newPassword, confirmNewPassword, ...otherFields } = formData;\n\tconst userData: Partial<SchemaUser & { password: string }> = {\n\t\t...otherFields,\n\t};\n\tif (newPassword && newPassword === confirmNewPassword) {\n\t\tuserData.password = newPassword;\n\t}\n\tconst { data } = await apiClient.patch(`/User/${id}` as '/User/{id}', userData);\n\treturn data as Partial<User>;\n}\n\nexport function useUpdateUserMutation() {\n\treturn useMutation({\n\t\tmutationFn: (formData: z.infer<typeof UpdateUserSchema>) => onUpdateUser(formData),\n\t});\n}\n","import { z } from 'zod';\n\nexport const UpdateUserSchema = z\n\t.object({\n\t\tid: z.string(),\n\t\tfirstname: z\n\t\t\t.string({\n\t\t\t\terror: 'Please enter your first name.',\n\t\t\t})\n\t\t\t.min(2, { error: 'First name is required.' })\n\t\t\t.max(50, { error: 'First name must be less than 50 characters.' }),\n\t\tlastname: z\n\t\t\t.string({\n\t\t\t\terror: 'Please enter your last name.',\n\t\t\t})\n\t\t\t.min(2, { error: 'Last name is required.' })\n\t\t\t.max(50, { error: 'Last name must be less than 50 characters.' }),\n\t\tnewPassword: z\n\t\t\t.string({\n\t\t\t\terror: 'Please enter your new password.',\n\t\t\t})\n\t\t\t.min(8, { error: 'Password must be 8 characters or more.' })\n\t\t\t.or(z.string().max(0)),\n\t\tconfirmNewPassword: z\n\t\t\t.string()\n\t\t\t.optional(),\n\t})\n\t.refine((data) => data.newPassword === data.confirmNewPassword, {\n\t\terror: 'Passwords do not match',\n\t\tpath: ['confirmNewPassword'],\n\t});\n","import { Button } from '@/components/ui/button';\nimport { Form } from '@/components/ui/form/Form';\nimport { FormControl } from '@/components/ui/form/FormControl';\nimport { FormField } from '@/components/ui/form/FormField';\nimport { FormItem } from '@/components/ui/form/FormItem';\nimport { FormLabel } from '@/components/ui/form/FormLabel';\nimport { FormMessage } from '@/components/ui/form/FormMessage';\nimport { Input } from '@/components/ui/input';\nimport { logoutOnSuccess } from '@/features/auth/handlers/logoutOnSuccess';\nimport { authStore, OverallAppSignIn } from '@/features/auth/store/authStore';\nimport { useUpdateUserMutation } from '@/features/profile/mutations/updateUserMutation';\nimport { UpdateUserSchema } from '@/features/profile/mutations/updateUserSchema';\nimport { useCloudAuth } from '@/hooks/useAuth';\nimport { zodResolver } from '@hookform/resolvers/zod';\nimport { useNavigate, useRouter } from '@tanstack/react-router';\nimport { Save } from 'lucide-react';\nimport { useCallback } from 'react';\nimport { useForm } from 'react-hook-form';\nimport { toast } from 'sonner';\nimport { z } from 'zod';\n\nexport function ProfileIndex() {\n\tconst router = useRouter();\n\tconst navigate = useNavigate();\n\tconst { user } = useCloudAuth();\n\n\tconst methods = useForm({\n\t\tresolver: zodResolver(UpdateUserSchema),\n\t\tdefaultValues: {\n\t\t\tconfirmNewPassword: '',\n\t\t\tfirstname: user?.firstname || '',\n\t\t\tid: user?.id || '',\n\t\t\tlastname: user?.lastname || '',\n\t\t\tnewPassword: '',\n\t\t},\n\t});\n\tconst { control, handleSubmit, reset, formState: { defaultValues, isDirty, isValid } } = methods;\n\tconst { mutate: updateUser, isPending: isUpdatePending } = useUpdateUserMutation();\n\n\tconst onSubmitClick = useCallback(\n\t\tasync (formData: z.infer<typeof UpdateUserSchema>) => {\n\t\t\tif (formData) {\n\t\t\t\tupdateUser(formData, {\n\t\t\t\t\tonSuccess: (data) => {\n\t\t\t\t\t\treset({\n\t\t\t\t\t\t\t...defaultValues,\n\t\t\t\t\t\t\t...data,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tauthStore.updateUserForEntity(OverallAppSignIn, data);\n\t\t\t\t\t\tif (formData.newPassword) {\n\t\t\t\t\t\t\ttoast.success('Profile updated successfully!', {\n\t\t\t\t\t\t\t\tdescription: 'Please sign in with your new password.',\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tlogoutOnSuccess();\n\t\t\t\t\t\t\tvoid navigate({ to: '/sign-in' });\n\t\t\t\t\t\t\tvoid router.invalidate();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttoast.success('Profile updated successfully!');\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\t[defaultValues, navigate, reset, router, updateUser],\n\t);\n\n\treturn (\n\t\t<div className=\"mt-20 px-4 pt-4 md:px-12\">\n\t\t\t<h2 className=\"text-2xl font-light\">Profile</h2>\n\t\t\t<Form {...methods}>\n\t\t\t\t<form\n\t\t\t\t\tid=\"profile-edit-form\"\n\t\t\t\t\tname=\"profile-edit-form\"\n\t\t\t\t\tonSubmit={handleSubmit(onSubmitClick)}\n\t\t\t\t\tclassName=\"grid gap-4 my-4\"\n\t\t\t\t>\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"firstname\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">First Name</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"bg-purple-400 border-purple-400 dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"words\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"lastname\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Last Name</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"text\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"bg-purple-400 border-purple-400 dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"words\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<FormLabel className=\"pb-1\">Email</FormLabel>\n\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\ttype=\"email\"\n\t\t\t\t\t\t\tenterKeyHint=\"next\"\n\t\t\t\t\t\t\tautoComplete=\"email\"\n\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\tvalue={user?.email || ''}\n\t\t\t\t\t\t\tdisabled={true}\n\t\t\t\t\t\t\treadOnly={true}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</FormControl>\n\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"newPassword\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">New Password</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\t\tplaceholder=\"Optional\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"bg-purple-400 border-purple-400 dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<FormField\n\t\t\t\t\t\tcontrol={control}\n\t\t\t\t\t\tname=\"confirmNewPassword\"\n\t\t\t\t\t\trender={({ field }) => (\n\t\t\t\t\t\t\t<FormItem>\n\t\t\t\t\t\t\t\t<FormLabel className=\"pb-1\">Confirm New Password</FormLabel>\n\t\t\t\t\t\t\t\t<FormControl>\n\t\t\t\t\t\t\t\t\t<Input\n\t\t\t\t\t\t\t\t\t\ttype=\"password\"\n\t\t\t\t\t\t\t\t\t\tclassName=\"bg-purple-400 border-purple-400 dark:bg-black dark:border-black\"\n\t\t\t\t\t\t\t\t\t\tautoComplete=\"new-password\"\n\t\t\t\t\t\t\t\t\t\tautoCapitalize=\"none\"\n\t\t\t\t\t\t\t\t\t\t{...field}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</FormControl>\n\t\t\t\t\t\t\t\t<FormMessage />\n\t\t\t\t\t\t\t</FormItem>\n\t\t\t\t\t\t)}\n\t\t\t\t\t/>\n\n\t\t\t\t\t<div className=\"flex justify-between w-full\">\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\ttype=\"submit\"\n\t\t\t\t\t\t\tvariant=\"submit\"\n\t\t\t\t\t\t\tclassName=\"rounded-full\"\n\t\t\t\t\t\t\tdisabled={isUpdatePending || !isDirty || !isValid}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Save /> Update Profile\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t</div>\n\t\t\t\t</form>\n\t\t\t</Form>\n\t\t</div>\n\t);\n}\n"],"names":["z.object","z.string","zodResolver","useCallback","jsxs","jsx"],"mappings":"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"}
|