sveltekit-auth-example 5.1.3 → 5.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  - Add password complexity checking on /register and /profile pages (only checks for length currently despite what the pages say)
4
4
 
5
+ # 5.5.0
6
+
7
+ - Extract email templates into dedicated files under `src/lib/server/email/` (`password-reset.ts`, `verify-email.ts`)
8
+ - `src/lib/server/email/index.ts` re-exports all templates for clean imports
9
+
5
10
  # 5.1.3
6
11
 
7
12
  - Session timeout: automatically redirect to /login on session expiry via fetch interceptor (`src/lib/fetch-interceptor.ts`)
package/README.md CHANGED
@@ -1,6 +1,5 @@
1
1
  # SvelteKit Authentication and Authorization Example
2
2
 
3
- [![GitHub release](https://img.shields.io/github/v/release/nstuyvesant/sveltekit-auth-example)](https://github.com/nstuyvesant/sveltekit-auth-example/releases)
4
3
  [![License](https://img.shields.io/github/license/nstuyvesant/sveltekit-auth-example)](https://github.com/nstuyvesant/sveltekit-auth-example/blob/master/LICENSE)
5
4
  [![Node](https://img.shields.io/node/v/sveltekit-auth-example)](https://nodejs.org)
6
5
  [![Svelte](https://img.shields.io/badge/Svelte-5-orange)](https://svelte.dev)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sveltekit-auth-example",
3
3
  "description": "SvelteKit Authentication Example",
4
- "version": "5.1.3",
4
+ "version": "5.5.0",
5
5
  "author": "Nate Stuyvesant",
6
6
  "license": "https://github.com/nstuyvesant/sveltekit-auth-example/blob/master/LICENSE",
7
7
  "repository": {
@@ -0,0 +1,2 @@
1
+ export { sendPasswordResetEmail } from './password-reset'
2
+ export { sendVerificationEmail } from './verify-email'
@@ -0,0 +1,15 @@
1
+ import { DOMAIN, SENDGRID_SENDER } from '$env/static/private'
2
+ import { sendMessage } from '$lib/server/sendgrid'
3
+
4
+ export const sendPasswordResetEmail = async (toEmail: string, token: string) => {
5
+ await sendMessage({
6
+ to: { email: toEmail },
7
+ from: SENDGRID_SENDER,
8
+ subject: 'Password reset',
9
+ categories: ['account'],
10
+ html: `
11
+ <p><a href="${DOMAIN}/auth/reset/${token}">Reset my password</a>. Your browser will open and ask you to
12
+ provide a new password with a confirmation then redirect you to your login page.</p>
13
+ `
14
+ })
15
+ }
@@ -0,0 +1,16 @@
1
+ import { DOMAIN, SENDGRID_SENDER } from '$env/static/private'
2
+ import { sendMessage } from '$lib/server/sendgrid'
3
+
4
+ export const sendVerificationEmail = async (toEmail: string, token: string) => {
5
+ await sendMessage({
6
+ to: { email: toEmail },
7
+ from: SENDGRID_SENDER,
8
+ subject: 'Verify your email address',
9
+ categories: ['account'],
10
+ html: `
11
+ <p>Thanks for registering! Please verify your email address by clicking the link below:</p>
12
+ <p><a href="${DOMAIN}/auth/verify/${token}">Verify my email address</a></p>
13
+ <p>This link expires in 24 hours. If you did not register, you can safely ignore this email.</p>
14
+ `
15
+ })
16
+ }
@@ -1,10 +1,9 @@
1
1
  import type { Secret } from 'jsonwebtoken'
2
- import type { MailDataRequired } from '@sendgrid/mail'
3
2
  import type { RequestHandler } from './$types'
4
3
  import jwt from 'jsonwebtoken'
5
- import { JWT_SECRET, DOMAIN, SENDGRID_SENDER } from '$env/static/private'
4
+ import { JWT_SECRET } from '$env/static/private'
6
5
  import { query } from '$lib/server/db'
7
- import { sendMessage } from '$lib/server/sendgrid'
6
+ import { sendPasswordResetEmail } from '$lib/server/email'
8
7
 
9
8
  export const POST: RequestHandler = async event => {
10
9
  const body = await event.request.json()
@@ -12,26 +11,13 @@ export const POST: RequestHandler = async event => {
12
11
  const { rows } = await query(sql, [body.email])
13
12
 
14
13
  if (rows.length > 0) {
15
- const { userId } = rows[0]
16
- // Create JWT with userId expiring in 30 mins
17
- const secret = JWT_SECRET
18
- const token = jwt.sign({ subject: userId, purpose: 'reset-password' }, <Secret>secret, {
19
- expiresIn: '30m'
20
- })
21
-
22
- // Email URL with token to user
23
- const message: MailDataRequired = {
24
- to: { email: body.email },
25
- from: SENDGRID_SENDER,
26
- subject: 'Password reset',
27
- categories: ['account'],
28
- html: `
29
- <a href="${DOMAIN}/auth/reset/${token}">Reset my password</a>. Your browser will open and ask you to provide a
30
- new password with a confirmation then redirect you to your login page.
31
- `
32
- }
14
+ const token = jwt.sign(
15
+ { subject: rows[0].userId, purpose: 'reset-password' },
16
+ JWT_SECRET as Secret,
17
+ { expiresIn: '30m' }
18
+ )
33
19
  try {
34
- await sendMessage(message)
20
+ await sendPasswordResetEmail(body.email, token)
35
21
  } catch (err) {
36
22
  console.error('Failed to send password reset email:', err)
37
23
  // Still return 204 to avoid leaking whether the email exists in our system
@@ -1,10 +1,9 @@
1
1
  import { error, json } from '@sveltejs/kit'
2
2
  import type { RequestHandler } from './$types'
3
- import type { MailDataRequired } from '@sendgrid/mail'
4
3
  import jwt from 'jsonwebtoken'
5
- import { JWT_SECRET, DOMAIN, SENDGRID_SENDER } from '$env/static/private'
4
+ import { JWT_SECRET } from '$env/static/private'
6
5
  import { query } from '$lib/server/db'
7
- import { sendMessage } from '$lib/server/sendgrid'
6
+ import { sendVerificationEmail } from '$lib/server/email'
8
7
 
9
8
  export const POST: RequestHandler = async event => {
10
9
  let body: { email?: string; password?: string; firstName?: string; lastName?: string }
@@ -47,19 +46,7 @@ export const POST: RequestHandler = async event => {
47
46
  { expiresIn: '24h' }
48
47
  )
49
48
 
50
- const message: MailDataRequired = {
51
- to: { email: body.email },
52
- from: SENDGRID_SENDER,
53
- subject: 'Verify your email address',
54
- categories: ['account'],
55
- html: `
56
- <p>Thanks for registering! Please verify your email address by clicking the link below:</p>
57
- <p><a href="${DOMAIN}/auth/verify/${token}">Verify my email address</a></p>
58
- <p>This link expires in 24 hours. If you did not register, you can safely ignore this email.</p>
59
- `
60
- }
61
-
62
- await sendMessage(message)
49
+ await sendVerificationEmail(body.email, token)
63
50
 
64
51
  return json({
65
52
  message: 'Registration successful. Please check your email to verify your account.',