Skip to content

Commit

Permalink
feat ✨: add Supabase client and password update functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael-Obele committed Sep 7, 2024
1 parent 9392c34 commit 2d4275b
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 11 deletions.
Binary file modified bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
"@lordicon/element": "^1.9.0",
"@prisma/client": "^5.15.1",
"@sentry/sveltekit": "^7.113.0",
"@supabase/supabase-js": "^2.45.3",
"bcryptjs": "^2.4.3",
"bits-ui": "^0.21.13",
"bytemd": "^1.21.0",
Expand Down
10 changes: 10 additions & 0 deletions src/lib/supabaseClient.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { createClient } from "@supabase/supabase-js";

const supabaseUrl = process.env.SUPABASE_URL || '';
const supabaseKey = process.env.SUPABASE_ANON_KEY || '';

if (!supabaseUrl || !supabaseKey) {
throw new Error('Supabase URL and key must be defined');
}

export const supabase = createClient(supabaseUrl, supabaseKey);
51 changes: 51 additions & 0 deletions src/routes/(auth)/Profile/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ import { fail, redirect } from '@sveltejs/kit';
import type { Action, Actions, PageServerLoad } from './$types';
import { getDbInstance } from '$lib/database';
import type { Prisma } from '@prisma/client';
import bcrypt from 'bcryptjs'; // Import bcrypt

const db = getDbInstance();

export const load: PageServerLoad = async (event) => {
const sessionID = event.cookies.get('session');
const session = await event.locals.auth();
Expand Down Expand Up @@ -48,5 +51,53 @@ export const actions: Actions = {
},
hidePasswords: async ({}) => {
return { displayPassword: [] };
},
updatePassword: async ({ request, locals }) => {
const formData = await request.formData();
const currentPassword = formData.get('currentPassword') as string;
const userId = formData.get('id') as string;
const newPassword = formData.get('newPassword') as string;

if (!userId) {
return fail(401, {
error: "Unauthorized! \t If you used OAuth You can't change your password."
});
}

try {
// Verify the current password
const user = await db.user.findUnique({
where: { id: userId }
});

if (!user) {
return fail(404, { error: 'User not found' });
}

// Check if the user has a password hash
if (user.passwordHash) {
const correctPassword = await bcrypt.compare(currentPassword, user?.passwordHash);

if (!correctPassword) {
return fail(401, { error: 'Incorrect password' });
// Redirect to the profile page or return a success message
} else {
// Hash the new password using bcrypt
const hashedPassword = await bcrypt.hash(newPassword, 10);

// Update the user's password in the database
await db.user.update({
where: { id: userId },
data: {
passwordHash: hashedPassword // Store the hashed password
}
});
return { message: 'Password updated successfully!' };
}
}
} catch (error) {
console.error('Error updating password:', error);
return fail(500, { error: 'Failed to update password' });
}
}
};
2 changes: 1 addition & 1 deletion src/routes/(auth)/Profile/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<!-- Mini App List -->
<MiniAppList />
<!-- Account Settings -->
<AccountSettingsList />
<AccountSettingsList {form} />
<!-- Updates List -->
<LatestUpdatesList />
<!-- Favorite Apps -->
Expand Down
68 changes: 62 additions & 6 deletions src/routes/(auth)/Profile/AccountSettingsList.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<script lang="ts">
import { enhance } from '$app/forms';
import { page } from '$app/stores';
import type { ActionData } from './$types.js';
import { Card, CardHeader, CardContent, CardTitle } from '$lib/components/ui/card';
Expand All @@ -7,7 +8,13 @@
import { Button } from '$lib/components/ui/button';
import { Separator } from '$lib/components/ui/separator';
import { StarIcon } from 'lucide-svelte';
import * as Dialog from '$lib/components/ui/dialog';
import { Label } from '$lib/components/ui/label/index.js';
import { Input } from '$lib/components/ui/input/index.js';
export let form: ActionData;
let showPassword = false;
$: password = showPassword ? 'text' : 'password';
let userData = $page.data.user?.userData;
</script>

Expand All @@ -31,16 +38,64 @@ As of now, the component displays a "Coming Soon" message, indicating that the a
<CardTitle>Account Settings</CardTitle>
</CardHeader>
<CardContent class="grid gap-4">
<h3>Coming Soon</h3>
<!-- <div class="grid gap-2">
<div class="grid gap-2">
<div class="flex items-center justify-between">
<div>
<div class="font-semibold">Change Password</div>
<div class="text-sm text-muted-foreground">Update your password</div>
</div>
<Button size="sm">Change</Button>
<Dialog.Root>
<Dialog.Trigger>
<Button size="sm">Change</Button>
</Dialog.Trigger>
<Dialog.Content>
<form action="?/updatePassword" use:enhance method="POST">
<Dialog.Header>
<Dialog.Title>Are you sure absolutely sure?</Dialog.Title>
<Dialog.Description>
Changing your password is a permanent action. Make sure you remember your new
password, as you won't be able to recover your old one.
</Dialog.Description>
</Dialog.Header>
<input type="hidden" name="id" value={userData.id} />
<Label for="currentPassword">Current Password:</Label>
<Input type={password} id="currentPassword" name="currentPassword" required />

<Label for="newPassword">New Password:</Label>
<Input type={password} id="newPassword" name="newPassword" required />
<span class="my-3 flex items-center">
<input
type="checkbox"
bind:checked={showPassword}
name="showPassword"
id="showPassword"
class="form-checkbox mx-2 h-5 w-5 text-indigo-600"
/>
<Label
for="showPassword"
class="ml-2 text-sm text-gray-700 hover:cursor-pointer dark:text-gray-200"
>Show Passwords</Label
>
</span>

<Dialog.Footer>
<Button type="submit">Save changes</Button>
</Dialog.Footer>
{#if form?.error}
<p class="mt-2 text-sm text-red-500 dark:text-red-400">{form?.error}</p>
{:else if form?.message}
<p class="mt-2 text-sm text-green-500 dark:text-green-400">{form?.message}</p>
{/if}
</form>
</Dialog.Content>
</Dialog.Root>
</div>
<div class="flex items-center justify-between">
{#if form?.error}
<p class="mt-2 text-sm text-red-500 dark:text-red-400">{form?.error}</p>
{:else if form?.message}
<p class="mt-2 text-sm text-green-500 dark:text-green-400">{form?.message}</p>
{/if}
<!-- <div class="flex items-center justify-between">
<div>
<div class="font-semibold">Update Email</div>
<div class="text-sm text-muted-foreground">Change your email address</div>
Expand All @@ -60,7 +115,8 @@ As of now, the component displays a "Coming Soon" message, indicating that the a
<div class="text-sm text-muted-foreground">Update your name and profile picture</div>
</div>
<Button size="sm">Edit</Button>
</div>
</div> -->
</div> -->
</div>
<h3>More Coming Soon</h3>
</CardContent>
</Card>
10 changes: 6 additions & 4 deletions src/routes/+page.server.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { redirect } from '@sveltejs/kit';
import type { PageServerLoad, Actions, RequestEvent } from './$types';

export const load: PageServerLoad = async (event) => {
if (event.url.href == 'https://svelte-mini-apps.netlify.app/') {
redirect(301, 'https://svelte-apps.me/');
}
import { supabase } from '$lib/supabaseClient';

export const load: PageServerLoad = async (event) => {
if (event.url.href == 'https://svelte-mini-apps.netlify.app/') {
redirect(301, 'https://svelte-apps.me/');
}
};

// export const actions: Actions = {
Expand Down

0 comments on commit 2d4275b

Please sign in to comment.