-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: create account change password form
- Loading branch information
hywax
committed
Aug 5, 2024
1 parent
1a4710d
commit a27ae4f
Showing
15 changed files
with
222 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
<template> | ||
<UForm | ||
ref="form" | ||
:state="state" | ||
:schema="accountChangePasswordSchema" | ||
@submit="onSubmit" | ||
> | ||
<UPageCard | ||
:title="$t('account.changePassword.title')" | ||
:description="$t('account.changePassword.description')" | ||
> | ||
<div class="space-y-4"> | ||
<UFormGroup | ||
:label="$t('account.changePassword.form.currentPassword.label')" | ||
name="currentPassword" | ||
required | ||
> | ||
<UInput | ||
v-model="state.currentPassword" | ||
size="md" | ||
type="password" | ||
:placeholder="$t('account.changePassword.form.currentPassword.placeholder')" | ||
/> | ||
</UFormGroup> | ||
<UFormGroup | ||
:label="$t('account.changePassword.form.newPassword.label')" | ||
name="newPassword" | ||
required | ||
> | ||
<UInput | ||
v-model="state.newPassword" | ||
size="md" | ||
type="password" | ||
:placeholder="$t('account.changePassword.form.newPassword.placeholder')" | ||
/> | ||
</UFormGroup> | ||
<UFormGroup | ||
:label="$t('account.changePassword.form.confirmPassword.label')" | ||
name="confirmPassword" | ||
required | ||
> | ||
<UInput | ||
v-model="state.confirmPassword" | ||
size="md" | ||
type="password" | ||
:placeholder="$t('account.changePassword.form.confirmPassword.placeholder')" | ||
/> | ||
</UFormGroup> | ||
</div> | ||
<template #footer-left> | ||
<UButton size="lg" type="submit" :loading="status === 'pending'"> | ||
{{ $t('account.changePassword.form.action.change') }} | ||
</UButton> | ||
</template> | ||
</UPageCard> | ||
</UForm> | ||
</template> | ||
|
||
<script setup lang="ts"> | ||
import type { Form } from '#ui/types' | ||
import { type AccountChangePasswordSchema, accountChangePasswordSchema } from '#schema' | ||
const form = ref<Form<AccountChangePasswordSchema>>() | ||
const state = reactive({ | ||
currentPassword: '', | ||
newPassword: '', | ||
confirmPassword: '', | ||
}) | ||
const toast = useToast() | ||
const { status, execute: onSubmit } = useAPI('/api/account/change-password', { | ||
method: 'PUT', | ||
body: state, | ||
immediate: false, | ||
watch: false, | ||
onResponse: async ({ response }) => { | ||
if (response.ok) { | ||
toast.add({ | ||
color: 'green', | ||
description: $t('account.changePassword.form.action.changed'), | ||
}) | ||
} | ||
}, | ||
}) | ||
</script> |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { z } from 'zod' | ||
|
||
export const accountChangePasswordSchema = z.object({ | ||
currentPassword: z.string().min(6), | ||
newPassword: z.string().min(6), | ||
confirmPassword: z.string().min(6), | ||
}).refine((data) => data.newPassword === data.confirmPassword, { | ||
path: ['confirmPassword'], | ||
}) | ||
|
||
export type AccountChangePasswordSchema = z.input<typeof accountChangePasswordSchema> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export * from './auth' | ||
export * from './account' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { ERROR_ACCOUNT_PASSWORD_INVALID_DATA, ERROR_ACCOUNT_PASSWORD_NOT_MATCH } from '#constants/errors' | ||
import { accountChangePassword } from '#services/account' | ||
|
||
export default defineEventHandler(async (event) => { | ||
try { | ||
const data = await readBody(event) | ||
const session = await getUserSession(event) | ||
|
||
await accountChangePassword({ | ||
userId: session.user!.id, | ||
currentPassword: data.currentPassword, | ||
newPassword: data.newPassword, | ||
}) | ||
} catch (e) { | ||
throw errorResolver(e, { | ||
ZOD: ERROR_ACCOUNT_PASSWORD_INVALID_DATA, | ||
ERROR_INVALID_PASSWORD: ERROR_ACCOUNT_PASSWORD_NOT_MATCH, | ||
}) | ||
} | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,16 @@ | ||
export const ERROR_BAD_REQUEST = '400000: Bad request' | ||
export const ERROR_USER_INVALID_DATA = '400001: Invalid user data' | ||
export const ERROR_USER_INVALID_CREDENTIALS = '400002: Invalid email or password' | ||
export const ERROR_ACCOUNT_PASSWORD_INVALID_DATA = '400003: Invalid password data' | ||
export const ERROR_ACCOUNT_PASSWORD_NOT_MATCH = '400004: Passwords do not match' | ||
export const ERROR_UNAUTHORIZED = '401000: Unauthorized' | ||
export const ERROR_FORBIDDEN = '403000: Forbidden' | ||
export const ERROR_ACCESS_ONLY_GUEST = '403001: Access only for guest' | ||
export const ERROR_ACCESS_ONLY_AUTHORIZED = '403002: Access only for authorized users' | ||
export const ERROR_ACCESS_ONLY_ADMIN = '403003: Access only for admin' | ||
export const ERROR_REGISTRATION_DISABLED = '403004: Registration is disabled' | ||
export const ERROR_NOT_FOUND = '404000: Not found' | ||
export const ERROR_USER_NOT_FOUND = '404001: User not found' | ||
export const ERROR_USER_ALL_READY_EXISTS = '409001: User with this email already exists' | ||
export const ERROR_INTERNAL_ERROR = '500000: Internal server error' | ||
export const ERROR_NOT_IMPLEMENTED = '501000: Not implemented' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { z } from 'zod' | ||
import bcrypt from 'bcrypt' | ||
import { eq } from 'drizzle-orm' | ||
import { tables, useDatabase } from '#db' | ||
import type { User } from '#db' | ||
|
||
interface AccountChangePasswordData { | ||
userId: User['id'] | ||
currentPassword: string | ||
newPassword: string | ||
} | ||
|
||
export async function accountChangePassword(data: AccountChangePasswordData): Promise<void> { | ||
const db = useDatabase() | ||
const changePasswordSchema = z.object({ | ||
userId: z.string(), | ||
currentPassword: z.string().min(6), | ||
newPassword: z.string().min(6), | ||
}) | ||
|
||
const { userId, currentPassword, newPassword } = changePasswordSchema.parse(data) | ||
const user = await db.query.users.findFirst({ | ||
where: (user, { eq }) => eq(user.id, userId), | ||
}) | ||
|
||
if (!user) { | ||
throw new Error('User not found') | ||
} | ||
|
||
const isMatch = await bcrypt.compare(currentPassword, user.password) | ||
|
||
if (!isMatch) { | ||
throw new Error('Invalid password') | ||
} | ||
|
||
await db.update(tables.users) | ||
.set({ password: await bcrypt.hash(newPassword, 10) }) | ||
.where(eq(tables.users.id, userId)) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.