diff --git a/frontend/Dockerfile b/frontend/Dockerfile index 48b0429..2e48a2b 100644 --- a/frontend/Dockerfile +++ b/frontend/Dockerfile @@ -1,4 +1,4 @@ -FROM oven/bun:1.1.20 +FROM node:22 WORKDIR /app @@ -8,14 +8,15 @@ COPY ./bun.lockb ./ COPY . . # COPY ./.env.example ./.env -RUN bun install +RUN npm install ARG DATABASE_URL -RUN DATABASE_URL=$DATABASE_URL bun run db:migrate +RUN DATABASE_URL=$DATABASE_URL npm run db:migrate -RUN bun run build +RUN npm run build EXPOSE 3000 -ENTRYPOINT ["bun", "--bun", "run", "build"] +ENTRYPOINT ["node", "build"] + diff --git a/frontend/bun.lockb b/frontend/bun.lockb index d9aea3b..755fb9a 100755 Binary files a/frontend/bun.lockb and b/frontend/bun.lockb differ diff --git a/frontend/package.json b/frontend/package.json index 89aeda9..7a4da5b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -41,9 +41,11 @@ "dependencies": { "@lucia-auth/adapter-drizzle": "^1.0.7", "@prgm/sveltekit-progress-bar": "^2.0.0", + "@stripe/stripe-js": "^4.3.0", "@types/he": "^1.2.3", "apexcharts": "^3.44.0", "arctic": "^1.9.2", + "argon2": "^0.41.0", "bits-ui": "^0.21.13", "clsx": "^2.0.0", "cmdk-sv": "^0.0.13", @@ -59,6 +61,7 @@ "postgres": "^3.4.3", "qr-code-styling": "^1.6.0-rc.1", "resend": "^3.4.0", + "stripe": "^16.8.0", "svelte-sonner": "^0.3.10", "sveltekit-superforms": "^2.12.2", "tailwind-merge": "^2.0.0", diff --git a/frontend/src/lib/db/migrate.ts b/frontend/src/lib/db/migrate.ts index 1c9ea4c..a0f16ed 100644 --- a/frontend/src/lib/db/migrate.ts +++ b/frontend/src/lib/db/migrate.ts @@ -2,7 +2,7 @@ import { drizzle } from 'drizzle-orm/postgres-js' import { migrate } from 'drizzle-orm/postgres-js/migrator' import postgres from 'postgres' -const sql = postgres(Bun.env.DATABASE_URL ?? '', { max: 1 }) +const sql = postgres(process.env.DATABASE_URL ?? '', { max: 1 }) const db = drizzle(sql) await migrate(db, { migrationsFolder: 'drizzle' }) diff --git a/frontend/src/routes/(app)/dashboard/settings/security/+page.server.ts b/frontend/src/routes/(app)/dashboard/settings/security/+page.server.ts index 710ece1..bc648f8 100644 --- a/frontend/src/routes/(app)/dashboard/settings/security/+page.server.ts +++ b/frontend/src/routes/(app)/dashboard/settings/security/+page.server.ts @@ -11,6 +11,7 @@ import { project, shortener, user, visitor } from '$lib/db/schema' import { eq, inArray } from 'drizzle-orm' import { lucia } from '$lib/server/auth' import { env } from '$env/dynamic/private' +import * as argon2 from 'argon2' export const load = (async (event) => { return { @@ -41,18 +42,24 @@ export const actions: Actions = { return setError(form, 'old_password', 'User Not Found') } - const passwordMatch = await Bun.password.verify( - form.data.old_password, + if (!userData.password) { + return setError( + form, + 'old_password', + 'User is using other login method', + ) + } + + const passwordMatch = await argon2.verify( userData.password, + form.data.old_password, ) if (!passwordMatch) { return setError(form, 'old_password', 'Old Password Not Match') } - const newPassword = await Bun.password.hash( - form.data.new_password, - ) + const newPassword = await argon2.hash(form.data.new_password) await db .update(user) @@ -94,9 +101,37 @@ export const actions: Actions = { return setError(form, 'password', 'User Not Found') } - const passwordMatch = await Bun.password.verify( - form.data.password, + if (userData.googleId) { + await lucia.invalidateUserSessions(userId) + + await db.delete(user).where(eq(user.id, userId)) + + const shorteners = await db + .delete(shortener) + .where(eq(shortener.userId, userId)) + .returning() + + await db.delete(project).where(eq(project.userId, userId)) + + await db.delete(visitor).where( + inArray( + visitor.shortenerId, + shorteners.map((shortener) => shortener.id), + ), + ) + + return { + form, + } + } + + if (!userData.password) { + return setError(form, 'password', 'User Not Found') + } + + const passwordMatch = await argon2.verify( userData.password, + form.data.password, ) if (!passwordMatch) { diff --git a/frontend/src/routes/(auth)/login/+page.server.ts b/frontend/src/routes/(auth)/login/+page.server.ts index 346b148..88d6efe 100644 --- a/frontend/src/routes/(auth)/login/+page.server.ts +++ b/frontend/src/routes/(auth)/login/+page.server.ts @@ -8,6 +8,7 @@ import { user as userSchema } from '$lib/db/schema' import { eq } from 'drizzle-orm' import { lucia } from '$lib/server/auth' import { env } from '$env/dynamic/private' +import * as argon2 from 'argon2' export const load = (async (event) => { return { @@ -44,8 +45,7 @@ export const actions: Actions = { } const matchPassword = - user && - (await Bun.password.verify(form.data.password, user.password)) + user && (await argon2.verify(user.password, form.data.password)) if (!user || !matchPassword) { return setError(form, 'email', 'Invalid credentials') diff --git a/frontend/src/routes/(auth)/signup/+page.server.ts b/frontend/src/routes/(auth)/signup/+page.server.ts index 4179452..d27094b 100644 --- a/frontend/src/routes/(auth)/signup/+page.server.ts +++ b/frontend/src/routes/(auth)/signup/+page.server.ts @@ -9,6 +9,7 @@ import { eq } from 'drizzle-orm' import { lucia } from '$lib/server/auth' import { env } from '$env/dynamic/private' import { sendEmailVerification } from '$lib/server/email' +import * as argon2 from 'argon2' export const load = (async (event) => { return { @@ -47,7 +48,7 @@ export const actions: Actions = { return setError(form, 'email', 'Email Already Exist') } - const hashedPassword = await Bun.password.hash(form.data.password) + const hashedPassword = await argon2.hash(form.data.password) const returnUsers = await db .insert(userSchema) .values({