Skip to content

Commit 393e5e2

Browse files
authored
Merge pull request #992 from joshunrau/password-strength
2 parents 2a24e43 + e255606 commit 393e5e2

2 files changed

Lines changed: 40 additions & 18 deletions

File tree

apps/web/src/features/admin/pages/CreateUserPage.tsx

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/* eslint-disable perfectionist/sort-objects */
22

3+
import { estimatePasswordStrength } from '@douglasneuroinformatics/libpasswd';
34
import { Form, Heading } from '@douglasneuroinformatics/libui/components';
45
import { useTranslation } from '@douglasneuroinformatics/libui/hooks';
56
import { $BasePermissionLevel, $CreateUserData, type CreateUserData } from '@opendatacapture/schemas/user';
@@ -44,6 +45,9 @@ export const CreateUserPage = () => {
4445
variant: 'input'
4546
},
4647
password: {
48+
calculateStrength: (password) => {
49+
return estimatePasswordStrength(password).score;
50+
},
4751
kind: 'string',
4852
label: t('common.password'),
4953
variant: 'password'
@@ -76,10 +80,19 @@ export const CreateUserPage = () => {
7680
variant: 'select'
7781
},
7882
groupIds: {
79-
kind: 'set',
80-
label: t('common.groups'),
81-
options: Object.fromEntries((groupsQuery.data ?? []).map((group) => [group.id, group.name])),
82-
variant: 'listbox'
83+
kind: 'dynamic',
84+
deps: ['basePermissionLevel'],
85+
render({ basePermissionLevel }) {
86+
if (!basePermissionLevel || basePermissionLevel === 'ADMIN') {
87+
return null;
88+
}
89+
return {
90+
kind: 'set',
91+
label: t('common.groups'),
92+
options: Object.fromEntries((groupsQuery.data ?? []).map((group) => [group.id, group.name])),
93+
variant: 'listbox'
94+
};
95+
}
8396
}
8497
}
8598
},
@@ -121,10 +134,19 @@ export const CreateUserPage = () => {
121134
})
122135
.extend({
123136
basePermissionLevel: $BasePermissionLevel,
124-
groupIds: z.set(z.string()),
137+
groupIds: z.set(z.string()).optional(),
125138
confirmPassword: z.string().min(1)
126139
})
127140
.superRefine((arg, ctx) => {
141+
if (!estimatePasswordStrength(arg.password).success) {
142+
ctx.addIssue({
143+
code: z.ZodIssueCode.custom,
144+
fatal: true,
145+
message: t('common.insufficientPasswordStrength'),
146+
path: ['password']
147+
});
148+
return z.NEVER;
149+
}
128150
if (arg.confirmPassword !== arg.password) {
129151
ctx.addIssue({
130152
code: z.ZodIssueCode.custom,
@@ -133,7 +155,7 @@ export const CreateUserPage = () => {
133155
});
134156
}
135157
})}
136-
onSubmit={(data) => handleSubmit({ ...data, groupIds: Array.from(data.groupIds) })}
158+
onSubmit={(data) => handleSubmit({ ...data, groupIds: Array.from(data.groupIds ?? []) })}
137159
/>
138160
</div>
139161
);

pnpm-lock.yaml

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)