Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
bab6665
Integrate Better Auth as enterprise auth provider
scopsy Dec 18, 2025
c5fad11
Refactor better-auth token handling and update dependencies
scopsy Dec 18, 2025
52b29c6
Add organization dropdown and user button components
scopsy Dec 18, 2025
243bd87
Add custom organization create component to better-auth
scopsy Dec 18, 2025
da40699
Replace useNavigate with window.location for redirects
scopsy Dec 19, 2025
42f9bad
Add invitation acceptance and team management features
scopsy Dec 19, 2025
91c8c69
Add session refresh and agent logging to invitation flow
scopsy Dec 19, 2025
d0ea007
Remove agent logging and improve invitation flow
scopsy Dec 21, 2025
70a4ec8
Refactor better-auth client and context usage
scopsy Dec 21, 2025
5572efe
Integrate Better Auth organization and user settings
scopsy Dec 21, 2025
070dde4
Implement RBAC role-permission mapping and UI updates
scopsy Dec 21, 2025
706266d
Update .source
scopsy Dec 21, 2025
375299e
Merge branch 'next' into better-auth-integration
scopsy Dec 22, 2025
b29928f
Remove Better Auth docs and update auth/cors logic
scopsy Dec 23, 2025
fa3fb66
Update cors.config.ts
scopsy Dec 23, 2025
c6d48ad
Add @novu/providers and @novu/stateless to auth package
scopsy Dec 23, 2025
41eb68a
Add forgot and reset password flows to dashboard
scopsy Dec 23, 2025
002dd1b
Add SSO sign-in support to dashboard app
scopsy Dec 23, 2025
4b97bda
Update .source
scopsy Dec 23, 2025
4ab3945
Delete vite.config.ts.timestamp-1766066097527-6e75268139a32.mjs
scopsy Dec 23, 2025
1f77b7c
Update .source
scopsy Dec 23, 2025
5001bee
Add email verification flow to dashboard auth
scopsy Dec 23, 2025
bb981ce
Merge branch 'next' into better-auth-integration
scopsy Jan 7, 2026
a89cbfb
Merge branch 'next' into better-auth-integration
scopsy Jan 11, 2026
c1633a4
Refactor region imports and update team member invite logic
scopsy Jan 11, 2026
3e7d05e
Handle pending invitation redirects during auth flow
scopsy Jan 11, 2026
24004ab
Remove mapRoleToApiFormat and simplify invite role handling
scopsy Jan 11, 2026
7498f63
Update auth checks and self-hosted env variable
scopsy Jan 11, 2026
917430e
Update .source
scopsy Jan 11, 2026
8769373
Update verify-email.tsx
scopsy Jan 11, 2026
7b3d3a3
Update .source
scopsy Jan 11, 2026
796b5e9
Switch auth pages to better-auth for non-Clerk providers
scopsy Jan 11, 2026
5a70c70
1.4.10 update
scopsy Jan 11, 2026
be3f1f8
Revert "1.4.10 update"
scopsy Jan 12, 2026
6b26502
Update .source
scopsy Jan 12, 2026
88b4006
Update auth and feature flag logic for enterprise/self-hosted
scopsy Jan 12, 2026
2933f0f
Merge branch 'next' into better-auth-integration
scopsy Jan 14, 2026
f2c4268
Merge branch 'next' into better-auth-integration
scopsy Jan 16, 2026
ca02dd3
Merge branch 'next' into better-auth-integration
scopsy Jan 18, 2026
18eb801
Update .source
scopsy Jan 18, 2026
9c783c3
Fix type safety and scroll handling in auth components
scopsy Jan 18, 2026
c21f16d
Enforce permission checks for org settings and members
scopsy Jan 18, 2026
6884564
Pin zod dependency to version 3.23.8
scopsy Jan 18, 2026
73291ad
Remove debug console logs and add permission usage check
scopsy Jan 18, 2026
00fdfcc
Move role permissions to shared package
scopsy Jan 18, 2026
778cac9
Update zod to version 3.25.0
scopsy Jan 18, 2026
b68b7d7
Fixes ad
scopsy Jan 18, 2026
b2398c0
Migrate dashboard to zod v4 and update resolvers
scopsy Jan 18, 2026
b1b4cf7
Update better-auth to ^1.3.0 and refresh lockfile
scopsy Jan 18, 2026
effa45a
Refactor Zod schema and validation type usage
scopsy Jan 18, 2026
7d8b39a
Refactor form validation to use standardSchemaResolver
scopsy Jan 18, 2026
26bfcc1
Improve type safety for workflow test payloads
scopsy Jan 18, 2026
6cc0e8f
Update .cspell.json
scopsy Jan 18, 2026
776d848
Update test-workflow-instructions.tsx
scopsy Jan 18, 2026
bb4bd1b
Merge branch 'next' into better-auth-integration
scopsy Jan 25, 2026
30fe477
Update sign-in.tsx
scopsy Jan 25, 2026
5c8075f
Update .source
scopsy Jan 25, 2026
cab81dd
Update .source
scopsy Jan 25, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Migrate dashboard to zod v4 and update resolvers
Upgraded zod from v3 to v4 and @hookform/resolvers to v5 in the dashboard app. Refactored schema usage to use new zod v4 methods (e.g., z.email(), z.url(), z.uuid(), z.looseObject()) and updated validation logic accordingly. This ensures compatibility with the latest zod API and improves type safety and maintainability.
  • Loading branch information
scopsy committed Jan 18, 2026
commit b2398c0a36be74d41de10856fd80578176d04da7
4 changes: 2 additions & 2 deletions apps/dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
"@codemirror/lang-html": "^6.4.9",
"@codemirror/lang-liquid": "^6.2.3",
"@codemirror/language": "^6.11.1",
"@hookform/resolvers": "^3.10.0",
"@hookform/resolvers": "^5.2.2",
"@inkeep/cxkit-react": "^0.5.107",
"@lezer/highlight": "^1.2.1",
"@novu/api": "workspace:*",
Expand Down Expand Up @@ -128,7 +128,7 @@
"tailwindcss-animate": "^1.0.7",
"use-deep-compare-effect": "^1.8.1",
"uuid": "^11.1.0",
"zod": "^3.23.8"
"zod": "^4.0.0"
},
"devDependencies": {
"@biomejs/biome": "2.2.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { PermissionButton } from '../primitives/permission-button';
import { Popover, PopoverContent, PopoverPortal, PopoverTrigger } from '../primitives/popover';
import { Tooltip, TooltipContent, TooltipTrigger } from '../primitives/tooltip';

const formSchema = z.object({ bridgeUrl: z.string().url() });
const formSchema = z.object({ bridgeUrl: z.url() });

export const EditBridgeUrlButton = () => {
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const baseJsonSchema: z.ZodType<any> = z

// Defines an item in our editable property list
const PropertyListItemSchema = z.object({
id: z.string().uuid(),
id: z.uuid(),
keyName: z
.string()
.min(1, { message: 'Property name is required.' })
Expand Down
4 changes: 2 additions & 2 deletions apps/dashboard/src/components/subscribers/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { z } from 'zod';
export const SubscriberFormSchema = z.object({
firstName: z.string().optional(),
lastName: z.string().optional(),
email: z.string().email().optional().nullable(),
email: z.email().optional().nullable(),
phone: z
.string()
.refine(isValidPhoneNumber, { message: 'Invalid phone number' })
Expand Down Expand Up @@ -40,7 +40,7 @@ export const CreateSubscriberFormSchema = SubscriberFormSchema.extend({
email: z
.string()
.trim()
.refine((val) => val === '' || z.string().email().safeParse(val).success, {
.refine((val) => val === '' || z.email().safeParse(val).success, {
message: 'Invalid email',
}),
locale: z.string().optional(),
Expand Down
30 changes: 14 additions & 16 deletions apps/dashboard/src/components/workflow-editor/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,17 @@ export const buildDynamicFormSchema = ({
let zodValue: z.ZodString | z.ZodNumber | z.ZodOptional<z.ZodString | z.ZodNumber>;

if (value.type === 'string') {
zodValue = z.string().min(1);

if (key === 'subscriberId') {
zodValue = zodValue.regex(
VALID_ID_REGEX,
'SubscriberId must be a string of alphanumeric characters, -, _, and . or a valid email address.'
);
}

if (value.format === 'email') {
zodValue = zodValue.email();
zodValue = z.email();
} else {
zodValue = z.string().min(1);

if (key === 'subscriberId') {
zodValue = zodValue.regex(
VALID_ID_REGEX,
'SubscriberId must be a string of alphanumeric characters, -, _, and . or a valid email address.'
);
}
}
} else {
zodValue = z.number().min(1);
Expand All @@ -80,11 +80,9 @@ export const buildDynamicFormSchema = ({
}, {});

return z.object({
to: z
.object({
...keys,
})
.passthrough(),
to: z.looseObject({
...keys,
}),
payload: z.string().transform((str, ctx) => {
try {
return JSON.parse(str);
Expand Down Expand Up @@ -118,5 +116,5 @@ const WorkflowPreferencesSchema = z.object({

export const UserPreferencesFormSchema = z.object({
user: WorkflowPreferencesSchema.nullable(),
severity: z.nativeEnum(SeverityLevelEnum).default(SeverityLevelEnum.NONE),
severity: z.enum(Object.values(SeverityLevelEnum) as [string, ...string[]]).default(SeverityLevelEnum.NONE),
});
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,11 @@ const getRuleSchema = (

return z.union([
z
.object({
.looseObject({
field: z.string().min(1),
operator: z.string(),
value: z.string().nullable(),
})
.passthrough()
.superRefine(({ field, operator, value }, ctx) => {
if (operator === 'between' || operator === 'notBetween') {
const values = value?.split(',').filter((val) => val.trim() !== '');
Expand Down Expand Up @@ -138,12 +137,10 @@ const getRuleSchema = (
ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Value is not valid', path: ['field'] });
}
}),
z
.object({
combinator: z.string(),
rules: z.array(z.lazy(() => getRuleSchema(fields, isAllowedVariableFn))),
})
.passthrough(),
z.looseObject({
combinator: z.string(),
rules: z.array(z.lazy(() => getRuleSchema(fields, isAllowedVariableFn))),
}),
]);
};

Expand All @@ -156,12 +153,10 @@ const getConditionsSchema = (
isAllowedVariableFn: (variable: { name: string }) => boolean
): z.ZodType<FormQuery> => {
return z.object({
query: z
.object({
combinator: z.string(),
rules: z.array(getRuleSchema(fields, isAllowedVariableFn)),
})
.passthrough(),
query: z.looseObject({
combinator: z.string(),
rules: z.array(getRuleSchema(fields, isAllowedVariableFn)),
}),
});
};

Expand Down
4 changes: 2 additions & 2 deletions apps/dashboard/src/utils/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ export type ZodValue =

const handleStringFormat = ({ value, key, format }: { value: z.ZodString; key: string; format: string }) => {
if (format === 'email') {
return value.email();
return z.email();
} else if (format === 'uri') {
return value
.transform((val) => (val === '' ? undefined : val))
.refine((val) => !val || z.string().url().safeParse(val).success, {
.refine((val) => !val || z.url().safeParse(val).success, {
message: `${capitalize(key)} must be a valid URI`,
});
}
Expand Down
Loading
Loading