upd: login
Deskripsi: - pembaruan login - batasan login No Issues
This commit is contained in:
17
src/app/(application)/layout.tsx
Normal file
17
src/app/(application)/layout.tsx
Normal file
@@ -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}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@ import { unsealData } from "iron-session";
|
|||||||
import { cookies } from "next/headers";
|
import { cookies } from "next/headers";
|
||||||
|
|
||||||
export async function GET() {
|
export async function GET() {
|
||||||
const sessionCookie = cookies().get("sessionCookie");
|
const sessionCookie = cookies().get("sessionCookieSDM");
|
||||||
const userId = await unsealData(sessionCookie!.value, {
|
const userId = await unsealData(sessionCookie!.value, {
|
||||||
password: pwd_key_config,
|
password: pwd_key_config,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,26 +1,31 @@
|
|||||||
|
|
||||||
import { prisma } from "@/module/_global";
|
import { prisma } from "@/module/_global";
|
||||||
import { ILogin } from "@/types";
|
import { ILogin } from "@/types";
|
||||||
import { NextRequest } from "next/server";
|
import { NextRequest } from "next/server";
|
||||||
|
|
||||||
export async function POST(req: NextRequest) {
|
export async function POST(req: NextRequest) {
|
||||||
const { phone }: ILogin = await req.json();
|
try {
|
||||||
const user = await prisma.user.findUnique({
|
const { phone }: ILogin = await req.json();
|
||||||
where: { phone, isActive: true },
|
const user = await prisma.user.findUnique({
|
||||||
select: { id: true, phone: true },
|
where: { phone, isActive: true },
|
||||||
});
|
select: { id: true, phone: true },
|
||||||
|
|
||||||
if (!user) {
|
|
||||||
return Response.json({
|
|
||||||
success: false,
|
|
||||||
message: "Email atau Password salah",
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return Response.json({
|
if (!user) {
|
||||||
success: true,
|
return Response.json({
|
||||||
message: "Login Berhasil",
|
success: false,
|
||||||
phone: user.phone,
|
message: "Nomor telepon tidak terdaftar",
|
||||||
id: user.id,
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
|
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 });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { cookies } from "next/headers";
|
import { cookies } from "next/headers";
|
||||||
|
|
||||||
export async function DELETE() {
|
export async function DELETE() {
|
||||||
cookies().delete('sessionCookie')
|
cookies().delete('sessionCookieSDM')
|
||||||
|
|
||||||
return Response.json({ success: true })
|
return Response.json({ success: true })
|
||||||
}
|
}
|
||||||
@@ -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 });
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,16 @@
|
|||||||
import { ViewLogin } from "@/module/auth";
|
import { pwd_key_config } from "@/module/_global";
|
||||||
import { Box, Image, rem, Stack, Text } from "@mantine/core";
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<ViewLogin/>
|
<ViewLogin />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
15
src/module/auth/api/funDetectCookies.ts
Normal file
15
src/module/auth/api/funDetectCookies.ts
Normal file
@@ -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
|
||||||
|
}
|
||||||
44
src/module/auth/api/funSetCookies.ts
Normal file
44
src/module/auth/api/funSetCookies.ts
Normal file
@@ -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 };
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import funDetectCookies from "./api/funDetectCookies";
|
||||||
|
import funSetCookies from "./api/funSetCookies";
|
||||||
import ViewLogin from "./login/view/view_login";
|
import ViewLogin from "./login/view/view_login";
|
||||||
import ViewVerification from "./varification/view/view_verification";
|
import ViewVerification from "./varification/view/view_verification";
|
||||||
import { ViewWelcome } from "./welcome/view_welcome";
|
import { ViewWelcome } from "./welcome/view_welcome";
|
||||||
@@ -5,3 +7,5 @@ import { ViewWelcome } from "./welcome/view_welcome";
|
|||||||
export { ViewLogin }
|
export { ViewLogin }
|
||||||
export { ViewVerification }
|
export { ViewVerification }
|
||||||
export { ViewWelcome }
|
export { ViewWelcome }
|
||||||
|
export { funSetCookies }
|
||||||
|
export { funDetectCookies }
|
||||||
@@ -32,7 +32,11 @@ function ViewLogin() {
|
|||||||
|
|
||||||
async function onLogin() {
|
async function onLogin() {
|
||||||
if (isPhone == "")
|
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', {
|
const cek = await fetch('/api/auth/login', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
@@ -40,29 +44,30 @@ function ViewLogin() {
|
|||||||
},
|
},
|
||||||
body: JSON.stringify({ phone: isPhone })
|
body: JSON.stringify({ phone: isPhone })
|
||||||
})
|
})
|
||||||
const json = await cek.json()
|
const cekLogin = await cek.json()
|
||||||
console.log(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=${cekLogin.phone}&text=${code}`).then(
|
||||||
const res = await fetch(`https://wa.wibudev.com/code?nom=${json.phone}&text=${code}`).then(
|
async (res) => {
|
||||||
async (res) => {
|
if (res.status == 200) {
|
||||||
if (res.status == 200) {
|
setValPhone(cekLogin.phone)
|
||||||
setValPhone(json.phone)
|
setOTP(code)
|
||||||
setOTP(code)
|
setUser(cekLogin.id)
|
||||||
setUser(json.id)
|
setVerif(true)
|
||||||
setVerif(true)
|
setLoading(false)
|
||||||
setLoading(false)
|
toast.success('Kode verifikasi telah dikirim')
|
||||||
toast.success('OTP sent successfully')
|
} else {
|
||||||
} else {
|
toast.error('Internal Server Error')
|
||||||
toast.error('OTP not sent')
|
setLoading(false)
|
||||||
setLoading(false)
|
}
|
||||||
}
|
}
|
||||||
console.log("code", code)
|
)
|
||||||
}
|
} else {
|
||||||
)
|
return toast.error(cekLogin.message)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,19 +92,19 @@ function ViewLogin() {
|
|||||||
radius={30}
|
radius={30}
|
||||||
leftSection={<Text>+62</Text>}
|
leftSection={<Text>+62</Text>}
|
||||||
placeholder="XXX XXX XXX"
|
placeholder="XXX XXX XXX"
|
||||||
onChange={(val) => { setPhone(val.target.value) }}
|
onChange={(val) => { setPhone('62' + val.target.value) }}
|
||||||
/>
|
/>
|
||||||
<Text fz={10} mt={10} c={WARNA.biruTua}>
|
<Text fz={10} mt={10} c={WARNA.biruTua}>
|
||||||
{textInfo}
|
{textInfo}
|
||||||
</Text>
|
</Text>
|
||||||
<Checkbox
|
{/* <Checkbox
|
||||||
mt={20}
|
mt={20}
|
||||||
label={
|
label={
|
||||||
<Text fz={10} c={WARNA.biruTua}>
|
<Text fz={10} c={WARNA.biruTua}>
|
||||||
Ingat saya
|
Ingat saya
|
||||||
</Text>
|
</Text>
|
||||||
}
|
}
|
||||||
/>
|
/> */}
|
||||||
<Box mt={20}>
|
<Box mt={20}>
|
||||||
<Button
|
<Button
|
||||||
c={"white"}
|
c={"white"}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { Anchor, Box, Button, Group, PinInput, Stack, Text, Title } from "@manti
|
|||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import toast from "react-hot-toast";
|
import toast from "react-hot-toast";
|
||||||
|
import funSetCookies from "../../api/funSetCookies";
|
||||||
|
|
||||||
export default function ViewVerification({ phone, otp, user }: IVerification) {
|
export default function ViewVerification({ phone, otp, user }: IVerification) {
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@@ -19,10 +20,10 @@ export default function ViewVerification({ phone, otp, user }: IVerification) {
|
|||||||
.then(
|
.then(
|
||||||
async (res) => {
|
async (res) => {
|
||||||
if (res.status == 200) {
|
if (res.status == 200) {
|
||||||
toast.success('Verification code has been sent')
|
toast.success('Kode verifikasi telah dikirim')
|
||||||
setOTP(code)
|
setOTP(code)
|
||||||
} else {
|
} else {
|
||||||
toast.error('Error')
|
toast.error('Internal Server Error')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -31,19 +32,22 @@ export default function ViewVerification({ phone, otp, user }: IVerification) {
|
|||||||
async function getVerification() {
|
async function getVerification() {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
if (isOTP == inputOTP) {
|
if (isOTP == inputOTP) {
|
||||||
|
const setCookies = await funSetCookies({ user: user })
|
||||||
|
|
||||||
|
if (setCookies.success) {
|
||||||
|
toast.success(setCookies.message)
|
||||||
|
if (setCookies.pertamaLogin == true)
|
||||||
|
return router.replace('/welcome')
|
||||||
|
console.log(setCookies.pertamaLogin)
|
||||||
|
return router.replace('/home')
|
||||||
|
} else {
|
||||||
|
toast.error(setCookies.message)
|
||||||
|
}
|
||||||
|
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
const res = await fetch('/api/auth/set-cookies', {
|
|
||||||
method: 'POST',
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
},
|
|
||||||
body: JSON.stringify({ user: user })
|
|
||||||
})
|
|
||||||
router.push('/welcome')
|
|
||||||
toast.success("Verification code is correct")
|
|
||||||
setLoading(false)
|
|
||||||
} else {
|
} else {
|
||||||
toast.error("Verification code is incorrect")
|
toast.error("Kode verifikasi salah")
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,7 +66,7 @@ export default function ViewVerification({ phone, otp, user }: IVerification) {
|
|||||||
Masukkan kode yang kami kirimkan melalui WhatsApp
|
Masukkan kode yang kami kirimkan melalui WhatsApp
|
||||||
</Text>
|
</Text>
|
||||||
<Text fz={12} c={WARNA.biruTua} fw={"bold"}>
|
<Text fz={12} c={WARNA.biruTua} fw={"bold"}>
|
||||||
{phone}
|
{'+' + phone}
|
||||||
</Text>
|
</Text>
|
||||||
<Box pt={30}>
|
<Box pt={30}>
|
||||||
<PinInput
|
<PinInput
|
||||||
@@ -89,19 +93,20 @@ export default function ViewVerification({ phone, otp, user }: IVerification) {
|
|||||||
size="md"
|
size="md"
|
||||||
radius={30}
|
radius={30}
|
||||||
fullWidth
|
fullWidth
|
||||||
|
loading={isLoading}
|
||||||
onClick={() => { getVerification() }}
|
onClick={() => { getVerification() }}
|
||||||
>
|
>
|
||||||
Lanjut
|
Lanjut
|
||||||
</Button>
|
</Button>
|
||||||
</Box>
|
</Box>
|
||||||
<Group justify="center" >
|
<Group justify="center" mt={5}>
|
||||||
<Text fz={12} c={WARNA.biruTua}>
|
<Text fz={12} c={WARNA.biruTua}>
|
||||||
Didnt receive a code ? {""}
|
Tidak menerima kode verifikasi? {""}
|
||||||
<Anchor c={WARNA.biruTua}
|
<Anchor c={WARNA.biruTua}
|
||||||
fz={12}
|
fz={12}
|
||||||
onClick={() => { onResend() }}
|
onClick={() => { onResend() }}
|
||||||
>
|
>
|
||||||
Resend
|
Kirim Ulang
|
||||||
</Anchor>
|
</Anchor>
|
||||||
</Text>
|
</Text>
|
||||||
</Group>
|
</Group>
|
||||||
|
|||||||
Reference in New Issue
Block a user