Skip to content

Commit

Permalink
Add js-sha256 for Gravatar URL generation; refactor UserMenu to use e…
Browse files Browse the repository at this point in the history
…mail for avatar; update setup schema to remove username
  • Loading branch information
haukened committed Nov 5, 2024
1 parent 7570a1f commit c7e9318
Show file tree
Hide file tree
Showing 7 changed files with 25 additions and 29 deletions.
2 changes: 1 addition & 1 deletion messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@
"title": "WireGuard Web",
"toggleTheme": "Toggle Theme",
"users": "Users"
}
}
9 changes: 8 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
"@oslojs/encoding": "^1.1.0",
"@sveltejs/adapter-node": "^5.2.9",
"better-sqlite3": "^11.1.2",
"drizzle-orm": "^0.33.0"
"drizzle-orm": "^0.33.0",
"js-sha256": "^0.11.0"
}
}
17 changes: 12 additions & 5 deletions src/lib/components/custom/UserMenu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,26 @@
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
import * as Avatar from '$lib/components/ui/avatar';
import * as m from '$lib/paraglide/messages';
import type { UserInfo } from '$lib/types';
import type { User } from '$lib/server/db';
import { sha256 } from 'js-sha256';
import { goto } from "$app/navigation";
import { LogOut, User, Users, RectangleEllipsis, Sun, Moon, House } from 'lucide-svelte';
import { LogOut, User as UserIcon, Users, RectangleEllipsis, Sun, Moon, House } from 'lucide-svelte';
import { toggleMode } from 'mode-watcher';
let { user }: { user: UserInfo | null } = $props();
let { user }: { user: User | null } = $props();
const gravatarURL = (email: string): string => {
if (!email) return `https://www.gravatar.com/avatar/0000?d=404`;
const hash = sha256.create().update(email.trim().toLowerCase()).hex();
return `https://www.gravatar.com/avatar/${hash}?d=404`
};
</script>

{#if user}
<DropdownMenu.Root>
<DropdownMenu.Trigger>
<Avatar.Root class="h-10 w-10">
<Avatar.Image src={user.gravatar ? user.gravatar : "https://gravatar.com/avatar/0000?d=404"} alt={user.firstname + " " + user.lastname} />
<Avatar.Image src={gravatarURL(user.email)} alt={user.firstname + " " + user.lastname} />
<Avatar.Fallback>{user.firstname?.charAt(0).toUpperCase() + user.lastname?.charAt(0).toUpperCase()}</Avatar.Fallback>
</Avatar.Root>
</DropdownMenu.Trigger>
Expand All @@ -27,7 +34,7 @@
<DropdownMenu.Group>
<DropdownMenu.GroupHeading>{m.myAccount()}</DropdownMenu.GroupHeading>
<DropdownMenu.Item onclick={() => goto('/profile')}>
<User class="mr-2 size-4"/>
<UserIcon class="mr-2 size-4"/>
{m.profile()}
</DropdownMenu.Item>
<DropdownMenu.Item onclick={() => goto('/password')}>
Expand Down
13 changes: 0 additions & 13 deletions src/lib/server/db/index.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,8 @@
import { drizzle } from 'drizzle-orm/better-sqlite3';
import { createHash } from 'crypto';
import Database from 'better-sqlite3';
const client = new Database( 'db.sqlite' );
export const db = drizzle(client);

/**
* Generates a Gravatar URL for the given email.
*
* @param email - The email address to generate the Gravatar URL for. If null, the function returns undefined.
* @returns The Gravatar URL for the given email, or undefined if the email is null.
*/
export const createGravatarURL = (email: string | null): string | undefined => {
if (!email) return undefined;
const hash = createHash('sha256').update(email.trim().toLowerCase()).digest('hex');
return `https://www.gravatar.com/avatar/${hash}?d=404`;
};

/**
* Checks if an email exists in the users table.
*
Expand Down
2 changes: 1 addition & 1 deletion src/routes/setup/+page.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ export const actions: Actions = {
firstname: form.data.firstname,
lastname: form.data.lastname,
email: form.data.email,
username: form.data.username,
password: hash,
last_login: new Date(Date.now()),
}).returning()
newId = result[0].id;
} catch (e) {
Expand Down
8 changes: 1 addition & 7 deletions src/routes/setup/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,7 @@ export const setupFormSchema = z.object({
firstname: z.string(),
lastname: z.string(),
email: z.string()
.email('Invalid email address')
.max(255, 'Email must be at most 255 characters long')
.optional(),
username: z.string()
.min(5, 'Must be at least 5 characters long')
.max(20, 'Username must be at most 20 characters long')
.regex(/^[a-zA-Z0-9_]+$/, 'Username must only contain letters, numbers, and underscores'),
.email('Invalid email address'),
password: z.string()
.min(8, 'Password must be at least 8 characters long')
.max(255, 'Password must be at most 255 characters long')
Expand Down

0 comments on commit c7e9318

Please sign in to comment.