-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
118 additions
and
49 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
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,57 @@ | ||
import { Context } from "hono" | ||
import { luciaAuth } from "../../auth/lucia" | ||
import { Scrypt } from "oslo/password" | ||
import { getConnection } from "@/v2/db/turso" | ||
import { authCredentials, authUser } from "@/v2/db/schema" | ||
import { createInsertSchema } from "drizzle-zod" | ||
import { z } from "zod" | ||
import { generateID } from "../../oslo" | ||
|
||
const authUserInsertSchema = createInsertSchema(authUser).pick({ | ||
username: true, | ||
email: true, | ||
}) | ||
|
||
export class UserAuthenticationManager { | ||
constructor(private ctx: Context) {} | ||
private lucia = luciaAuth(this.ctx.env as Bindings) | ||
private drizzleInstance = getConnection(this.ctx.env).drizzle | ||
|
||
public async createAccount( | ||
attributes: Required<z.infer<typeof authUserInsertSchema>>, | ||
password: string | ||
) { | ||
const createUserTransaction = await this.drizzleInstance.transaction( | ||
async (db) => { | ||
try { | ||
const [newUser] = await db | ||
.insert(authUser) | ||
.values({ | ||
id: generateID(), | ||
username: attributes.username, | ||
email: attributes.email, | ||
}) | ||
.returning() | ||
|
||
await db.insert(authCredentials).values({ | ||
id: generateID(20), | ||
userId: newUser.id, | ||
hashedPassword: await new Scrypt().hash(password), | ||
}) | ||
|
||
return newUser | ||
} catch (e) { | ||
await db.rollback() | ||
} | ||
} | ||
) | ||
|
||
await this.lucia.createSession(createUserTransaction.id, { | ||
user_agent: this.ctx.req.header("user-agent") || "", | ||
ip_address: this.ctx.req.header("cf-connecting-ip") || "", | ||
country_code: this.ctx.req.header("cf-ipcountry") || "", | ||
}) | ||
|
||
return createUserTransaction.id | ||
} | ||
} |
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,11 +1,11 @@ | ||
import { Context } from "hono" | ||
import { auth } from "../../auth/lucia" | ||
import { luciaAuth } from "../../auth/lucia" | ||
|
||
export class AuthSessionManager { | ||
constructor(private ctx: Context) {} | ||
private auth = auth(this.ctx.env as Bindings) | ||
private lucia = luciaAuth(this.ctx.env as Bindings) | ||
|
||
async validateSession(sessionId: string) { | ||
return await this.auth.validateSession(sessionId) | ||
return await this.lucia.validateSession(sessionId) | ||
} | ||
} |
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,5 +1,5 @@ | ||
import { generateRandomString, alphabet } from "oslo/random" | ||
|
||
export function generateID() { | ||
return generateRandomString(15, alphabet("a-z", "0-9")).toLowerCase() | ||
export function generateID(length: number = 15) { | ||
return generateRandomString(length, alphabet("a-z", "0-9")).toLowerCase() | ||
} |
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 |
---|---|---|
|
@@ -3,9 +3,9 @@ import type { Context } from "hono" | |
|
||
const emailFrom = "Test <[email protected]>" | ||
|
||
const sendEmail = async (emailData: EmailData, c: Context) => { | ||
const sendEmail = async (emailData: EmailData, ctx: Context) => { | ||
try { | ||
const resend = new Resend(c) | ||
const resend = new Resend(ctx) | ||
await resend.sendEmail(emailData) | ||
} catch (error) { | ||
throw new Error(`[RESEND]: ${error.message}`) | ||
|
@@ -29,52 +29,52 @@ export const sendPasswordResetEmail = async ( | |
email: string, | ||
link: string, | ||
username: string, | ||
c: Context | ||
ctx: Context | ||
) => { | ||
const emailData = createEmailData( | ||
email, | ||
"Password Reset Request", | ||
`<strong>Password reset for ${username}</strong><br /><a href="${link}">Click here to reset your password</a>` | ||
) | ||
return sendEmail(emailData, c) | ||
return sendEmail(emailData, ctx) | ||
} | ||
|
||
export const sendPasswordChangeEmail = async ( | ||
email: string, | ||
username: string, | ||
c: Context | ||
ctx: Context | ||
) => { | ||
const emailData = createEmailData( | ||
email, | ||
"Password Change Request", | ||
`<strong>Your password for ${username} has been changed.</strong><br /> Wasn't you? Contact us at <a href="mailto:[email protected]">[email protected]</a>` | ||
) | ||
return sendEmail(emailData, c) | ||
return sendEmail(emailData, ctx) | ||
} | ||
|
||
export const sendEmailChangeEmail = async ( | ||
email: string, | ||
username: string, | ||
c: Context | ||
ctx: Context | ||
) => { | ||
const emailData = createEmailData( | ||
email, | ||
"Email Change Request", | ||
`<strong>Your email address for ${username} has been changed.</strong><br /> Wasn't you? Contact us at <a href="mailto:[email protected]">[email protected]</a>` | ||
) | ||
return sendEmail(emailData, c) | ||
return sendEmail(emailData, ctx) | ||
} | ||
|
||
export const sendEmailConfirmationEmail = async ( | ||
email: string, | ||
link: string, | ||
username: string, | ||
c: Context | ||
ctx: Context | ||
) => { | ||
const emailData = createEmailData( | ||
email, | ||
"Email Confirmation", | ||
`<strong>Email confirmation for ${username}</strong><br /><a href="${link}">Click here to confirm your email</a>` | ||
) | ||
return sendEmail(emailData, c) | ||
return sendEmail(emailData, ctx) | ||
} |
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,36 +1,36 @@ | ||
import type { Context, Next } from "hono" | ||
import { auth } from "@/v2/lib/auth/lucia" | ||
import type { Next } from "hono" | ||
import { luciaAuth } from "@/v2/lib/auth/lucia" | ||
import { getCookie } from "hono/cookie" | ||
|
||
export async function setUserVariable(c: Context, next: Next) { | ||
const setAuth = auth(c.env) | ||
export async function setUserVariable(ctx: APIContext, next: Next) { | ||
const lucia = luciaAuth(ctx.env) | ||
|
||
const sessionId = getCookie(c, setAuth.sessionCookieName) ?? null | ||
const sessionId = getCookie(ctx, lucia.sessionCookieName) ?? null | ||
|
||
if (!sessionId) { | ||
c.set("user", null) | ||
ctx.set("user", null) | ||
return next() | ||
} | ||
|
||
const { session, user } = await setAuth.validateSession(sessionId) | ||
const { session, user } = await lucia.validateSession(sessionId) | ||
|
||
if (session && session.fresh) { | ||
c.header( | ||
ctx.header( | ||
"Set-Cookie", | ||
setAuth.createSessionCookie(session.id).serialize(), | ||
lucia.createSessionCookie(session.id).serialize(), | ||
{ | ||
append: true, | ||
} | ||
) | ||
} | ||
|
||
if (!session) { | ||
c.header("Set-Cookie", setAuth.createBlankSessionCookie().serialize(), { | ||
ctx.header("Set-Cookie", lucia.createBlankSessionCookie().serialize(), { | ||
append: true, | ||
}) | ||
} | ||
|
||
c.set("user", user) | ||
ctx.set("user", user) | ||
|
||
return next() | ||
} |
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