Browse Source

add ability to set password for oidc users

this allows oidc users to add password login
cant be removed after
dev-oauth
Bernd Storath 1 week ago
parent
commit
c238b40af9
  1. 11
      src/app/pages/me.vue
  2. 1
      src/i18n/locales/en.json
  3. 1
      src/server/api/session.get.ts
  4. 25
      src/server/database/repositories/user/service.ts
  5. 2
      src/server/database/repositories/user/types.ts
  6. 2
      src/shared/utils/permissions.ts

11
src/app/pages/me.vue

@ -27,6 +27,7 @@
<FormGroup>
<FormHeading>{{ $t('general.password') }}</FormHeading>
<FormPasswordField
v-if="hasPassword"
id="current-password"
v-model="currentPassword"
autocomplete="current-password"
@ -46,7 +47,11 @@
/>
<FormSecondaryActionField
type="submit"
:label="$t('general.updatePassword')"
:label="
hasPassword
? $t('general.updatePassword')
: $t('general.addPassword')
"
/>
</FormGroup>
</FormElement>
@ -125,6 +130,7 @@ const authStore = useAuthStore();
const name = ref(authStore.userData?.name);
const email = ref(authStore.userData?.email);
const hasPassword = computed(() => authStore.userData?.hasPassword);
const _submit = useSubmit(
(data) =>
@ -158,13 +164,14 @@ const _updatePassword = useSubmit(
currentPassword.value = '';
newPassword.value = '';
confirmPassword.value = '';
return authStore.update();
},
}
);
function updatePassword() {
return _updatePassword({
currentPassword: currentPassword.value,
currentPassword: hasPassword.value ? currentPassword.value : null,
newPassword: newPassword.value,
confirmPassword: confirmPassword.value,
});

1
src/i18n/locales/en.json

@ -28,6 +28,7 @@
"password": "Password",
"newPassword": "New Password",
"updatePassword": "Update Password",
"addPassword": "Add Password",
"mtu": "MTU",
"allowedIps": "Allowed IPs",
"dns": "DNS",

1
src/server/api/session.get.ts

@ -26,5 +26,6 @@ export default defineEventHandler(async (event) => {
name: user.name,
email: user.email,
totpVerified: user.totpVerified,
hasPassword: user.password !== null,
} satisfies SharedPublicUser;
});

25
src/server/database/repositories/user/service.ts

@ -193,7 +193,11 @@ export class UserService {
return this.#statements.update.execute({ id, name, email });
}
async updatePassword(id: ID, currentPassword: string, newPassword: string) {
async updatePassword(
id: ID,
currentPassword: string | null,
newPassword: string
) {
const hash = await hashPassword(newPassword);
return this.#db.transaction(async (tx) => {
@ -206,13 +210,20 @@ export class UserService {
throw new Error('User not found');
}
const passwordValid = await isPasswordValid(
currentPassword,
txUser.password
);
// only check password if already set
if (txUser.password !== null) {
if (!currentPassword) {
throw new Error('Invalid password');
}
if (!passwordValid) {
throw new Error('Invalid password');
const passwordValid = await isPasswordValid(
currentPassword,
txUser.password
);
if (!passwordValid) {
throw new Error('Invalid password');
}
}
await tx

2
src/server/database/repositories/user/types.ts

@ -57,7 +57,7 @@ export const UserUpdateSchema = z.object({
export const UserUpdatePasswordSchema = z
.object({
currentPassword: password,
currentPassword: password.nullable(),
newPassword: password,
confirmPassword: password,
})

2
src/shared/utils/permissions.ts

@ -48,7 +48,7 @@ type SharedUserType =
export type SharedPublicUser = Pick<
UserType,
'id' | 'username' | 'name' | 'email' | 'totpVerified'
> & { role: BrandedNumber };
> & { role: BrandedNumber; hasPassword: boolean };
type PermissionCheck<Key extends keyof Permissions> =
| boolean

Loading…
Cancel
Save