From cffd993bc0396de261aa475ae24ad3152105628a Mon Sep 17 00:00:00 2001 From: amel Date: Tue, 30 Jul 2024 14:49:12 +0800 Subject: [PATCH 1/3] upd: update database --- prisma/schema.prisma | 83 ++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 41 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index ad0e0af..3131be4 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -24,31 +24,31 @@ model UserRole { } model Village { - id String @id @default(cuid()) - name String - desc String @db.Text - isActive Boolean @default(true) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - Group Group[] - User User[] + id String @id @default(cuid()) + name String + desc String @db.Text + isActive Boolean @default(true) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + Group Group[] + User User[] Announcement Announcement[] - Project Project[] - Division Division[] + Project Project[] + Division Division[] } model Group { - id String @id @default(cuid()) - Village Village @relation(fields: [idVillage], references: [id]) - idVillage String - name String - isActive Boolean @default(true) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - Position Position[] - User User[] - Project Project[] - Division Division[] + id String @id @default(cuid()) + Village Village @relation(fields: [idVillage], references: [id]) + idVillage String + name String + isActive Boolean @default(true) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + Position Position[] + User User[] + Project Project[] + Division Division[] AnnouncementMember AnnouncementMember[] } @@ -78,10 +78,11 @@ model User { phone String @unique email String? @unique gender String @default("M") //M= Male, F= Female + isFirstLogin Boolean @default(true) isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt - Announcement Announcement[] + Announcement Announcement[] Project Project[] ProjectMember ProjectMember[] ProjectComment ProjectComment[] @@ -110,30 +111,30 @@ model UserLog { } model Announcement { - id String @id @default(cuid()) - Village Village @relation(fields: [idVillage], references: [id]) - idVillage String - title String - desc String @db.Text - isActive Boolean @default(true) - User User @relation(fields: [createdBy], references: [id]) - createdBy String - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt + id String @id @default(cuid()) + Village Village @relation(fields: [idVillage], references: [id]) + idVillage String + title String + desc String @db.Text + isActive Boolean @default(true) + User User @relation(fields: [createdBy], references: [id]) + createdBy String + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt AnnouncementMember AnnouncementMember[] } model AnnouncementMember { - id String @id @default(cuid()) + id String @id @default(cuid()) Announcement Announcement @relation(fields: [idAnnouncement], references: [id]) idAnnouncement String - Group Group @relation(fields: [idGroup], references: [id]) - idGroup String - Division Division @relation(fields: [idDivision], references: [id]) - idDivision String - isActive Boolean @default(true) - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt + Group Group @relation(fields: [idGroup], references: [id]) + idGroup String + Division Division @relation(fields: [idDivision], references: [id]) + idDivision String + isActive Boolean @default(true) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt } model Project { @@ -203,7 +204,7 @@ model Division { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt DivisionMember DivisionMember[] - AnnouncementMember AnnouncementMember[] + AnnouncementMember AnnouncementMember[] DivisionProject DivisionProject[] DivisionProjectTask DivisionProjectTask[] DivisionProjectMember DivisionProjectMember[] From 1607152d77eaea3236d7b1071f5009dbc5b4ab8b Mon Sep 17 00:00:00 2001 From: amel Date: Tue, 30 Jul 2024 14:50:51 +0800 Subject: [PATCH 2/3] upd: login Deskripsi: - pembaruan login - batasan login No Issues --- src/app/(application)/layout.tsx | 17 ++++++ src/app/api/auth/get-user-by-cookies/route.ts | 2 +- src/app/api/auth/login/route.ts | 41 +++++++------- src/app/api/auth/logout/route.ts | 2 +- src/app/api/auth/set-cookies/route.ts | 16 ------ src/app/page.tsx | 14 +++-- src/module/auth/api/funDetectCookies.ts | 15 ++++++ src/module/auth/api/funSetCookies.ts | 44 +++++++++++++++ src/module/auth/index.ts | 6 ++- src/module/auth/login/view/view_login.tsx | 53 ++++++++++--------- .../varification/view/view_verification.tsx | 39 ++++++++------ 11 files changed, 167 insertions(+), 82 deletions(-) create mode 100644 src/app/(application)/layout.tsx delete mode 100644 src/app/api/auth/set-cookies/route.ts create mode 100644 src/module/auth/api/funDetectCookies.ts create mode 100644 src/module/auth/api/funSetCookies.ts diff --git a/src/app/(application)/layout.tsx b/src/app/(application)/layout.tsx new file mode 100644 index 0000000..75575d1 --- /dev/null +++ b/src/app/(application)/layout.tsx @@ -0,0 +1,17 @@ +import { pwd_key_config } from "@/module/_global" +import { funDetectCookies } from "@/module/auth" +import { unsealData } from "iron-session" +import _ from "lodash" +import { cookies } from "next/headers" +import { redirect } from "next/navigation" + +export default async function Layout({ children }: { children: React.ReactNode }) { + const cookies = await funDetectCookies() + if (!cookies) return redirect('/') + + return ( + <> + {children} + + ); +} \ No newline at end of file diff --git a/src/app/api/auth/get-user-by-cookies/route.ts b/src/app/api/auth/get-user-by-cookies/route.ts index add8676..99798fa 100644 --- a/src/app/api/auth/get-user-by-cookies/route.ts +++ b/src/app/api/auth/get-user-by-cookies/route.ts @@ -3,7 +3,7 @@ import { unsealData } from "iron-session"; import { cookies } from "next/headers"; export async function GET() { - const sessionCookie = cookies().get("sessionCookie"); + const sessionCookie = cookies().get("sessionCookieSDM"); const userId = await unsealData(sessionCookie!.value, { password: pwd_key_config, }); diff --git a/src/app/api/auth/login/route.ts b/src/app/api/auth/login/route.ts index 519f463..c034ddb 100644 --- a/src/app/api/auth/login/route.ts +++ b/src/app/api/auth/login/route.ts @@ -1,26 +1,31 @@ - import { prisma } from "@/module/_global"; import { ILogin } from "@/types"; import { NextRequest } from "next/server"; export async function POST(req: NextRequest) { - const { phone }: ILogin = await req.json(); - const user = await prisma.user.findUnique({ - where: { phone, isActive: true }, - select: { id: true, phone: true }, - }); - - if (!user) { - return Response.json({ - success: false, - message: "Email atau Password salah", + try { + const { phone }: ILogin = await req.json(); + const user = await prisma.user.findUnique({ + where: { phone, isActive: true }, + select: { id: true, phone: true }, }); - } - return Response.json({ - success: true, - message: "Login Berhasil", - phone: user.phone, - id: user.id, - }); + if (!user) { + return Response.json({ + success: false, + message: "Nomor telepon tidak terdaftar", + }); + } + + return Response.json({ + success: true, + message: "Sukses", + phone: user.phone, + id: user.id, + }); + + } catch (error) { + console.log(error); + return Response.json({ message: "Internal Server Error", success: false }); + } } diff --git a/src/app/api/auth/logout/route.ts b/src/app/api/auth/logout/route.ts index c17ef71..29f11a1 100644 --- a/src/app/api/auth/logout/route.ts +++ b/src/app/api/auth/logout/route.ts @@ -1,7 +1,7 @@ import { cookies } from "next/headers"; export async function DELETE() { - cookies().delete('sessionCookie') + cookies().delete('sessionCookieSDM') return Response.json({ success: true }) } \ No newline at end of file diff --git a/src/app/api/auth/set-cookies/route.ts b/src/app/api/auth/set-cookies/route.ts deleted file mode 100644 index b201337..0000000 --- a/src/app/api/auth/set-cookies/route.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { pwd_key_config } from "@/module/_global"; -import { sealData } from "iron-session"; -import { cookies } from "next/headers"; -import { redirect } from "next/navigation"; - -export async function POST(req: Request) { - const { user } = await req.json(); - const encryptedUserData = await sealData(user, { password: pwd_key_config }); - - cookies().set({ - name: "sessionCookie", - value: encryptedUserData, - }); - - return Response.json({ success: true }); -} diff --git a/src/app/page.tsx b/src/app/page.tsx index fcd135f..4bec541 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -1,10 +1,16 @@ -import { ViewLogin } from "@/module/auth"; -import { Box, Image, rem, Stack, Text } from "@mantine/core"; +import { pwd_key_config } from "@/module/_global"; +import { funDetectCookies, ViewLogin } from "@/module/auth"; +import { unsealData } from "iron-session"; +import _ from "lodash"; +import { cookies } from "next/headers"; +import { redirect } from "next/navigation"; -export default function Home() { +export default async function Home() { + const cookies = await funDetectCookies() + if (cookies) return redirect('/home') return ( <> - + ); } diff --git a/src/module/auth/api/funDetectCookies.ts b/src/module/auth/api/funDetectCookies.ts new file mode 100644 index 0000000..e8fd0d4 --- /dev/null +++ b/src/module/auth/api/funDetectCookies.ts @@ -0,0 +1,15 @@ +'use server' +import { pwd_key_config } from "@/module/_global" +import { unsealData } from "iron-session" +import _ from "lodash" +import { cookies } from "next/headers" + +export default async function funDetectCookies() { + const cookiesnya = cookies() + const c = cookiesnya.get("sessionCookieSDM") + if (!c || _.isUndefined(c) || !c.value || _.isEmpty(c.value)) return false + const dataCookies = await unsealData(c!.value, { password: pwd_key_config as string }) + if (_.isEmpty(_.toString(dataCookies))) return false + + return true +} \ No newline at end of file diff --git a/src/module/auth/api/funSetCookies.ts b/src/module/auth/api/funSetCookies.ts new file mode 100644 index 0000000..965203f --- /dev/null +++ b/src/module/auth/api/funSetCookies.ts @@ -0,0 +1,44 @@ +'use server' +import { sealData } from "iron-session"; +import { cookies } from "next/headers"; +import { prisma, pwd_key_config } from "@/module/_global"; + +export default async function funSetCookies({ user }: { user: string }) { + try { + const encryptedUserData = await sealData(user, { password: pwd_key_config }); + + // data user + const dataUser = await prisma.user.findUnique({ + where: { + id: user + }, + select:{ + isFirstLogin: true + } + }) + + if (dataUser?.isFirstLogin) { + await prisma.user.update({ + where: { + id: user + }, + data: { + isFirstLogin: false + } + }) + } + + // set cookies + cookies().set({ + name: "sessionCookieSDM", + value: encryptedUserData, + }); + + + + return { success: true, message: "Login berhasil!", pertamaLogin: dataUser?.isFirstLogin }; + } catch (error) { + console.error(error); + return { message: "Internal Server Error", success: false }; + } +} \ No newline at end of file diff --git a/src/module/auth/index.ts b/src/module/auth/index.ts index 3f6d0c0..9c3273d 100644 --- a/src/module/auth/index.ts +++ b/src/module/auth/index.ts @@ -1,7 +1,11 @@ +import funDetectCookies from "./api/funDetectCookies"; +import funSetCookies from "./api/funSetCookies"; import ViewLogin from "./login/view/view_login"; import ViewVerification from "./varification/view/view_verification"; import { ViewWelcome } from "./welcome/view_welcome"; export { ViewLogin } export { ViewVerification } -export { ViewWelcome } \ No newline at end of file +export { ViewWelcome } +export { funSetCookies } +export { funDetectCookies } \ No newline at end of file diff --git a/src/module/auth/login/view/view_login.tsx b/src/module/auth/login/view/view_login.tsx index 8c5eb23..03a28ae 100644 --- a/src/module/auth/login/view/view_login.tsx +++ b/src/module/auth/login/view/view_login.tsx @@ -32,7 +32,11 @@ function ViewLogin() { async function onLogin() { if (isPhone == "") - return toast.error('Please fill in completely') + return toast.error('Silakan diisi dengan lengkap') + + if (isPhone.toString().length <= 11) + return toast.error('Nomor telepon tidak valid') + const cek = await fetch('/api/auth/login', { method: 'POST', headers: { @@ -40,29 +44,30 @@ function ViewLogin() { }, body: JSON.stringify({ phone: isPhone }) }) - const json = await cek.json() - console.log(json) + const cekLogin = await cek.json() - const code = Math.floor(Math.random() * 1000) + 1000 + if (cekLogin.success) { + const code = Math.floor(Math.random() * 1000) + 1000 + setLoading(true) - setLoading(true) - const res = await fetch(`https://wa.wibudev.com/code?nom=${json.phone}&text=${code}`).then( - async (res) => { - if (res.status == 200) { - setValPhone(json.phone) - setOTP(code) - setUser(json.id) - setVerif(true) - setLoading(false) - toast.success('OTP sent successfully') - } else { - toast.error('OTP not sent') - setLoading(false) + const res = await fetch(`https://wa.wibudev.com/code?nom=${cekLogin.phone}&text=${code}`).then( + async (res) => { + if (res.status == 200) { + setValPhone(cekLogin.phone) + setOTP(code) + setUser(cekLogin.id) + setVerif(true) + setLoading(false) + toast.success('Kode verifikasi telah dikirim') + } else { + toast.error('Internal Server Error') + setLoading(false) + } } - console.log("code", code) - } - ) - + ) + } else { + return toast.error(cekLogin.message) + } } @@ -87,19 +92,19 @@ function ViewLogin() { radius={30} leftSection={+62} placeholder="XXX XXX XXX" - onChange={(val) => { setPhone(val.target.value) }} + onChange={(val) => { setPhone('62' + val.target.value) }} /> {textInfo} - Ingat saya } - /> + /> */} - + - Didnt receive a code ? {""} + Tidak menerima kode verifikasi? {""} { onResend() }} > - Resend + Kirim Ulang From 739c0ed642e4e7deea0b62de8eabdb2db6ab3d12 Mon Sep 17 00:00:00 2001 From: amel Date: Tue, 30 Jul 2024 14:51:52 +0800 Subject: [PATCH 3/3] upd: perbarui seeder --- src/module/seeder/data/user.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/module/seeder/data/user.json b/src/module/seeder/data/user.json index a5d98c1..3077cd2 100644 --- a/src/module/seeder/data/user.json +++ b/src/module/seeder/data/user.json @@ -4,7 +4,7 @@ "idUserRole": "dev", "nik": "1111111", "name": "Amalia", - "phone": "6298980185458", + "phone": "628980185458", "email": "amalia@bip.com", "gender": "F" },