Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/change password dashboard #38

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion src/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
href="https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;700&family=Fira+Mono&display=swap"
rel="stylesheet"
/>
<link rel="icon" href="yabin-logo.ico" />
<link rel="icon" href="/yabin-logo.ico" />
<meta name="viewport" content="width=device-width" />
<title>YABin</title>

Expand Down
2 changes: 1 addition & 1 deletion src/routes/dashboard/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
</script>

<div class="p-2 min-h-screen w-screen flex flex-col text-primary">
<div class="pb-4">
<div>
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this empty div needed?

<div class="flex flex-row items-center gap-4">
<h1 class="mr-auto text-2xl"><a href="/">YABin</a></h1>

Expand Down
74 changes: 72 additions & 2 deletions src/routes/dashboard/settings/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,30 @@ import { redirect, type Actions } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';
import prisma from '@db';
import type { UserSettings } from '$lib/types';
import { validatePassword } from '$lib/server/validate';
import { hashPassword } from '$lib/crypto';
import { env } from '$env/dynamic/private';

export const load: PageServerLoad = async ({ cookies }) => {
const userId = await getUserIdFromCookie(cookies);
if (!userId) throw redirect(303, '/login');

const user = await prisma.user.findUnique({
where: { id: userId },
select: { settings: true },
select: {
settings: true,
username: true,
name: true,
email: true,
},
});

return { settings: user?.settings as UserSettings };
return {
settings: user?.settings as UserSettings,
username: user?.username as string,
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think we need to use as string, since it is already a string.

name: user?.name as string,
email: user?.email as string,
};
};

export const actions: Actions = {
Expand Down Expand Up @@ -47,4 +60,61 @@ export const actions: Actions = {
},
};
},
changePassword: async ({ cookies, request }) => {
const formData = await request.formData();
const token = cookies.get('token');
if (!token) {
return redirect(301, '/login');
}
const newPassword = formData.get('newPassword');
const confirmPassword = formData.get('confirmPassword');

if (!newPassword || !confirmPassword) {
return {
passwordForm: {
success: false,
error: 'Missing required fields',
},
};
}

if (newPassword !== confirmPassword) {
return {
passwordForm: {
success: false,
error: 'Passwords do not match',
},
};
}

try {
if (newPassword) validatePassword(newPassword);
} catch (err: any) {
return {
passwordForm: {
success: false,
error: err.message,
},
};
}

const userId = await getUserIdFromCookie(cookies);
if (userId && newPassword) {
const hash = await hashPassword(newPassword.toString(), env.SALT);
const user = await prisma.user.update({
where: {
id: userId,
},
data: {
password: hash,
},
});
}

return {
passwordForm: {
success: true,
},
};
},
};
190 changes: 126 additions & 64 deletions src/routes/dashboard/settings/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -43,79 +43,141 @@
<h1 class="text-5xl">Settings</h1>

<div class="px-4">
<h4 class="text-2xl mt-6 mb-4">Defaults</h4>
<div>
<h4 class="text-2xl mt-6 mb-4">User</h4>
<div class="grid grid-cols-3 px-4 py-1">
<div>
<div class="text-xl">Name</div>
<div class="opacity-80">{data?.name}</div>
</div>

<form
method="post"
action="?/defaults"
class="mt-2 flex flex-col gap-4"
use:enhance={() => {
return async ({ result }) => {
if (result.type === 'redirect') await goto(result.location);
else await applyAction(result);
};
}}
>
<div>
<label for="encrypted" class="py-2">Encrypted</label>
<input
id="encrypted"
class="bg-dark px-2 py-1"
type="checkbox"
name="encrypted"
checked={settings?.defaults?.encrypted}
/>
<div class="">
<div class="text-xl">Username</div>
<div class="opacity-80">{data?.username}</div>
</div>
<div>
<div class="text-xl">Email</div>
<div class="opacity-80">{data?.email}</div>
</div>
</div>

<div>
<label for="burn-after-read" class="py-2">Burn after read</label>
<input
id="burn-after-read"
class="bg-dark px-2 py-1"
type="checkbox"
name="burn-after-read"
checked={settings?.defaults?.burnAfterRead}
/>
</div>
<div>
<h4 class="text-2xl mt-6 mb-4">Change Password</h4>
<div class="px-3">
<form
method="post"
action="?/changePassword"
use:enhance
class="flex flex-col gap-7"
>
<div class="flex flex-col lg:w-[40%] w-[80%] gap-1">
<label for="newPassword">New Password:</label>
<input
type="newPassword"
name="newPassword"
class="bg-dark py-1 text-center"
/>
</div>
<div class="flex flex-col lg:w-[40%] w-[80%] gap-1">
<label for="confirmPassword">Confirm Password:</label>
<input
type="confirmPassword"
name="confirmPassword"
class="bg-dark py-1 text-center"
/>
</div>
<div class="">
<button class="bg-amber-500 text-black text-lg px-4 py-1"
>Save</button
>
{#if form?.passwordForm?.success}
<span class="text-green-500">Saved</span>
{/if}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can use if/else here instead of two different if statements.

{#if form?.passwordForm?.success === false}
<span class="text-red-800"
>{form.passwordForm?.error}</span
>
{/if}
</div>
</form>
</div>
</div>
<div>
<h4 class="text-2xl mt-6 mb-4">Defaults</h4>

<div>
<span>Expires in:</span>
<div class="grid grid-cols-3 gap-2 justify-center items-center">
<input
type="number"
class="bg-dark py-1 text-center"
placeholder="DD"
bind:value={expiresAfter.days}
/>
<input
type="number"
class="bg-dark py-1 text-center"
placeholder="HH"
bind:value={expiresAfter.hours}
/>
<form
method="post"
action="?/defaults"
class="mt-2 flex flex-col gap-4 px-3"
use:enhance={() => {
return async ({ result }) => {
if (result.type === 'redirect') await goto(result.location);
else await applyAction(result);
};
}}
>
<div>
<label for="encrypted" class="py-2">Encrypted</label>
<input
type="number"
class="bg-dark py-1 text-center"
placeholder="MM"
bind:value={expiresAfter.minutes}
id="encrypted"
class="bg-dark px-2 py-1"
type="checkbox"
name="encrypted"
checked={settings?.defaults?.encrypted}
/>
</div>

<div>
<label for="burn-after-read" class="py-2">Burn after read</label
>
<input
type="hidden"
name="expires-after-seconds"
bind:value={expiresAfterSeconds}
id="burn-after-read"
class="bg-dark px-2 py-1"
type="checkbox"
name="burn-after-read"
checked={settings?.defaults?.burnAfterRead}
/>
</div>
</div>

<div class="mt-2">
<button class="bg-amber-500 text-black text-lg px-4 py-1"
>Save</button
>
{#if form?.defaultsForm.success}
<span class="text-green-500">Saved</span>
<!-- {:else if form?.defaultsForm.error}
<div>
<span>Expires in:</span>
<div class="grid grid-cols-3 gap-2 justify-center items-center">
<input
type="number"
class="bg-dark py-1 text-center"
placeholder="DD"
bind:value={expiresAfter.days}
/>
<input
type="number"
class="bg-dark py-1 text-center"
placeholder="HH"
bind:value={expiresAfter.hours}
/>
<input
type="number"
class="bg-dark py-1 text-center"
placeholder="MM"
bind:value={expiresAfter.minutes}
/>
<input
type="hidden"
name="expires-after-seconds"
bind:value={expiresAfterSeconds}
/>
</div>
</div>

<div class="mt-2">
<button class="bg-amber-500 text-black text-lg px-4 py-1"
>Save</button
>
{#if form?.defaultsForm !== undefined && form?.defaultsForm.success}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can be simplied as {#if form?.defaultsForm?.success}

<span class="text-green-500">Saved</span>
<!-- {:else if form?.defaultsForm.error}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you remove the commented lines please?

<span class="text-red-500">Error</span> -->
{/if}
</div>
</form>
{/if}
</div>
</form>
</div>
</div>
Loading
Loading