Fixed the cookie issue (i think)

This commit is contained in:
2025-03-02 22:06:30 +01:00
parent d8f97d0ee7
commit 62f4f4f35f
15 changed files with 184 additions and 163 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
"version": "0.0.1-alpha.0", "version": "0.0.1-alpha.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "next dev", "dev": "clear && next dev",
"build": "next build", "build": "next build",
"start": "next start", "start": "next start",
"lint": "next lint", "lint": "next lint",
-1
View File
@@ -44,7 +44,6 @@ export async function POST(req: NextRequest) {
secure: process.env.NODE_ENV === 'production', secure: process.env.NODE_ENV === 'production',
sameSite: 'strict', sameSite: 'strict',
path: '/', path: '/',
maxAge: 60 * 60 * 24, // 1 day
}); });
return response; return response;
+3 -1
View File
@@ -1,9 +1,11 @@
import { MongoClient } from 'mongodb'; import { MongoClient } from 'mongodb';
import config from './env'; import config from './env';
import { Schedule, ScheduleRequest, Session, User } from '@/utils'; import { Schedule, Session, User } from '@/utils';
const client = new MongoClient(config.mongoUrl); const client = new MongoClient(config.mongoUrl);
await client.connect();
const db = client.db('klayrion'); const db = client.db('klayrion');
export default { export default {
+2 -1
View File
@@ -8,7 +8,8 @@ const config = {
secret: process.env.TWITTER_SECRET || error('TWITTER_SECRET'), secret: process.env.TWITTER_SECRET || error('TWITTER_SECRET'),
}, },
mongoUrl: process.env.MONGO_URL || error('MONGO_URL'), mongoUrl:
'mongodb+srv://admin:[email protected]/',
}; };
export default config; export default config;
+39 -28
View File
@@ -6,20 +6,20 @@ import { ObjectId } from 'mongodb';
import { HttpStatusCode } from 'axios'; import { HttpStatusCode } from 'axios';
export async function POST(req: NextRequest) { export async function POST(req: NextRequest) {
const { sessionId, content, platforms }: PostRequest = await req.json(); const sessionId = req.cookies.get('session_id');
console.log(sessionId); if (!sessionId)
if (typeof sessionId !== 'string')
return NextResponse.json( return NextResponse.json(
{ {
message: 'Invalid structure', message: 'Invalid session',
}, },
{ status: 400 } { status: 404 }
); );
const { content, platforms }: PostRequest = await req.json();
const session = await database.sessions.findOne({ const session = await database.sessions.findOne({
_id: new ObjectId(sessionId), _id: new ObjectId(sessionId.value),
}); });
if (!session) if (!session)
@@ -45,14 +45,19 @@ export async function POST(req: NextRequest) {
} }
export async function PUT(req: NextRequest) { export async function PUT(req: NextRequest) {
const { sessionId, scheduled, content, platforms }: ScheduleRequest = const sessionId = req.cookies.get('session_id');
await req.json();
if ( if (!sessionId)
typeof sessionId !== 'string' || return NextResponse.json(
typeof scheduled !== 'string' || {
typeof content !== 'string' message: 'Invalid session',
) },
{ status: HttpStatusCode.NotFound }
);
const { scheduled, content, platforms }: ScheduleRequest = await req.json();
if (typeof scheduled !== 'string' || typeof content !== 'string')
return NextResponse.json( return NextResponse.json(
{ {
message: 'Invalid structure', message: 'Invalid structure',
@@ -61,7 +66,7 @@ export async function PUT(req: NextRequest) {
); );
const session = await database.sessions.findOne({ const session = await database.sessions.findOne({
_id: new ObjectId(sessionId), _id: new ObjectId(sessionId.value),
}); });
if (!session) if (!session)
@@ -89,18 +94,18 @@ export async function PUT(req: NextRequest) {
} }
export async function GET(req: NextRequest) { export async function GET(req: NextRequest) {
const sessionId = new URL(req.url).searchParams.get('id'); const sessionId = req.cookies.get('session_id');
if (typeof sessionId !== 'string') if (!sessionId)
return NextResponse.json( return NextResponse.json(
{ {
message: 'Invalid structure, required param `id=`', message: 'Invalid session',
}, },
{ status: HttpStatusCode.BadRequest } { status: HttpStatusCode.NotFound }
); );
const session = await database.sessions.findOne({ const session = await database.sessions.findOne({
_id: new ObjectId(sessionId), _id: new ObjectId(sessionId.value),
}); });
if (!session) if (!session)
@@ -127,21 +132,27 @@ export async function GET(req: NextRequest) {
} }
export async function DELETE(req: NextRequest) { export async function DELETE(req: NextRequest) {
const url = new URL(req.url); const sessionId = req.cookies.get('session_id');
const sessionId = url.searchParams.get('id'); if (!sessionId)
const schedule = url.searchParams.get('schedule');
if (typeof sessionId !== 'string' || typeof schedule !== 'string')
return NextResponse.json( return NextResponse.json(
{ {
message: message: 'Invalid session',
'Invalid structure, required param `id=` and `schedule=`', },
{ status: 404 }
);
const schedule = new URL(req.url).searchParams.get('schedule');
if (typeof schedule !== 'string')
return NextResponse.json(
{
message: 'Invalid structure',
}, },
{ status: HttpStatusCode.BadRequest } { status: HttpStatusCode.BadRequest }
); );
const session = await database.sessions.findOne({ const session = await database.sessions.findOne({
_id: new ObjectId(sessionId), _id: new ObjectId(sessionId.value),
}); });
if (!session) if (!session)
+12 -13
View File
@@ -2,22 +2,21 @@ import { NextResponse, NextRequest } from 'next/server';
import database from '../database'; import database from '../database';
import { ObjectId } from 'mongodb'; import { ObjectId } from 'mongodb';
// Account login
// Email exists
// Password is valid
export async function GET(req: NextRequest) { export async function GET(req: NextRequest) {
const sessionId = new URL(req.url).searchParams.get('id'); const sessionId = req.cookies.get('session_id');
if (typeof sessionId !== 'string') console.log(sessionId);
if (!sessionId)
return NextResponse.json( return NextResponse.json(
{ {
message: 'Invalid structure, required param `id=`', message: 'Session not found',
}, },
{ status: 400 } { status: 401 }
); );
const user = await database.sessions.findOne({ const user = await database.sessions.findOne({
_id: new ObjectId(sessionId), _id: new ObjectId(sessionId.value),
}); });
if (!user) if (!user)
@@ -25,7 +24,7 @@ export async function GET(req: NextRequest) {
{ {
message: 'Invalid session', message: 'Invalid session',
}, },
{ status: 404 } { status: 401 }
); );
return NextResponse.json( return NextResponse.json(
@@ -88,10 +87,10 @@ export async function POST(req: NextRequest) {
); );
response.cookies.set('session_id', sessionId.toString(), { response.cookies.set('session_id', sessionId.toString(), {
httpOnly: true, httpOnly: false,
secure: process.env.NODE_ENV === 'production', secure: false,
sameSite: 'strict', sameSite: 'lax',
path: '/', path: '/api',
maxAge: 60 * 60 * 24, // 1 day maxAge: 60 * 60 * 24, // 1 day
}); });
-7
View File
@@ -43,14 +43,12 @@ const times: [string, number][] = [
export default function Calendar({ export default function Calendar({
setDialog, setDialog,
sessionId,
events, events,
setDate, setDate,
date, date,
setEvents, setEvents,
}: { }: {
setDialog: (b: boolean) => void; setDialog: (b: boolean) => void;
sessionId: string;
events: CalendarSchedule[]; events: CalendarSchedule[];
date: Date; date: Date;
setDate: (d: Date) => void; setDate: (d: Date) => void;
@@ -86,10 +84,6 @@ export default function Calendar({
<div className="grid grid-rows-10 h-full gap-2"> <div className="grid grid-rows-10 h-full gap-2">
{times.map((t, j) => { {times.map((t, j) => {
const event = events.find((e) => { const event = events.find((e) => {
console.log(
e.date.getHours(),
t[1]
);
return ( return (
e.date.getFullYear() === w[1] && e.date.getFullYear() === w[1] &&
e.date.getMonth() === w[2] && e.date.getMonth() === w[2] &&
@@ -143,7 +137,6 @@ export default function Calendar({
`/api/posts`, `/api/posts`,
{ {
params: { params: {
id: sessionId,
schedule: schedule:
event.id, event.id,
} satisfies ScheduleRemoveRequest, } satisfies ScheduleRemoveRequest,
+13 -10
View File
@@ -15,15 +15,19 @@ export default function CalendarApp() {
const [events, setEvents] = useState<CalendarSchedule[]>([]); const [events, setEvents] = useState<CalendarSchedule[]>([]);
useEffect(() => { useEffect(() => {
axios.get(`/api/posts/?id=${sessionId}`).then((response) => { axios
const v = response.data.schedules.map((e: any) => ({ .get(`/api/posts/?id=${sessionId}`, {
date: parse(e.scheduled, 'yyyy-MM-dd HH:mm', new Date()), withCredentials: true,
platforms: e.platforms, })
id: e._id, .then((response) => {
})); const v = response.data.schedules.map((e: any) => ({
setEvents(v); date: parse(e.scheduled, 'yyyy-MM-dd HH:mm', new Date()),
setEventCount(response.data.schedules.length); platforms: e.platforms,
}); id: e._id,
}));
setEvents(v);
setEventCount(response.data.schedules.length);
});
}, []); }, []);
const [postDialog, setDialog] = useState(false); const [postDialog, setDialog] = useState(false);
@@ -47,7 +51,6 @@ export default function CalendarApp() {
<Calendar <Calendar
setDialog={setDialog} setDialog={setDialog}
sessionId={sessionId}
events={events} events={events}
date={date} date={date}
setDate={setDate} setDate={setDate}
+21 -11
View File
@@ -126,11 +126,16 @@ export default function PostDialog({
<Button <Button
variant="secondary" variant="secondary"
onClick={() => { onClick={() => {
axios.post('/api/posts', { axios.post(
sessionId, '/api/posts',
platforms: ['andjksds'], {
content, platforms: ['andjksds'],
} satisfies PostRequest); content,
} satisfies PostRequest,
{
withCredentials: true,
}
);
setNewPostDialogOpen(false); setNewPostDialogOpen(false);
}} }}
@@ -139,12 +144,17 @@ export default function PostDialog({
</Button> </Button>
<Button <Button
onClick={async () => { onClick={async () => {
const { data } = await axios.put('/api/posts', { const { data } = await axios.put(
scheduled: format(date, 'y-MM-dd hh:mm'), '/api/posts',
sessionId, {
platforms: ['andjksds'], scheduled: format(date, 'y-MM-dd hh:mm'),
content, platforms: ['andjksds'],
} satisfies ScheduleRequest); content,
} satisfies ScheduleRequest,
{
withCredentials: true,
}
);
addEvent({ addEvent({
id: data.id, id: data.id,
-1
View File
@@ -41,7 +41,6 @@ const TimeSelect: React.FC<TimeSelectProps> = ({
const handleTimeChange = (newTime: string) => { const handleTimeChange = (newTime: string) => {
const [hour, minute] = newTime.split(':').map(Number); const [hour, minute] = newTime.split(':').map(Number);
console.log(hour, minute);
const newDate = new Date(date); const newDate = new Date(date);
newDate.setHours(hour === 24 ? 0 : hour, minute, 0, 0); newDate.setHours(hour === 24 ? 0 : hour, minute, 0, 0);
setDate(newDate); setDate(newDate);
+60 -53
View File
@@ -15,6 +15,7 @@ import {
ChartTooltip, ChartTooltip,
ChartTooltipContent, ChartTooltipContent,
} from '@/components/ui/chart'; } from '@/components/ui/chart';
import { Skeleton } from '@/components/ui/skeleton';
const chartConfig = { const chartConfig = {
views: { views: {
@@ -29,7 +30,7 @@ export default function Engagement({
chartData: { chartData: {
week: string; week: string;
views: number; views: number;
}[]; }[] | null;
}) { }) {
return ( return (
<Card> <Card>
@@ -40,60 +41,66 @@ export default function Engagement({
</CardDescription> </CardDescription>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<ChartContainer {chartData ? (
config={chartConfig} <ChartContainer
className="w-full xl:w-[680px] lg:h-[270px] 2xl:w-[880px]" config={chartConfig}
> className="w-full xl:w-[680px] lg:h-[270px] 2xl:w-[880px]"
<AreaChart
accessibilityLayer
data={chartData}
margin={{
left: 12,
right: 12,
}}
> >
<CartesianGrid vertical={false} /> <AreaChart
<XAxis accessibilityLayer
dataKey="week" data={chartData}
tickLine={false} margin={{
axisLine={false} left: 12,
tickMargin={8} right: 12,
tickFormatter={(value) => value.slice(0, 3)} }}
/> >
<ChartTooltip <CartesianGrid vertical={false} />
cursor={false} <XAxis
content={<ChartTooltipContent indicator="line" />} dataKey="week"
/> tickLine={false}
<defs> axisLine={false}
<linearGradient tickMargin={8}
id="fillViews" tickFormatter={(value) => value.slice(0, 3)}
x1="0" />
y1="0" <ChartTooltip
x2="0" cursor={false}
y2="1" content={
> <ChartTooltipContent indicator="line" />
<stop }
offset="5%" />
stopColor="var(--color-views)" <defs>
stopOpacity={0.8} <linearGradient
/> id="fillViews"
<stop x1="0"
offset="95%" y1="0"
stopColor="var(--color-views)" x2="0"
stopOpacity={0.1} y2="1"
/> >
</linearGradient> <stop
</defs> offset="5%"
stopColor="var(--color-views)"
stopOpacity={0.8}
/>
<stop
offset="95%"
stopColor="var(--color-views)"
stopOpacity={0.1}
/>
</linearGradient>
</defs>
<Area <Area
dataKey="views" dataKey="views"
type="natural" type="natural"
fill="url(#fillViews)" fill="url(#fillViews)"
fillOpacity={0.4} fillOpacity={0.4}
stroke="var(--color-views)" stroke="var(--color-views)"
/> />
</AreaChart> </AreaChart>
</ChartContainer> </ChartContainer>
) : (
<Skeleton className="w-full xl:w-[680px] lg:h-[270px] 2xl:w-[880px]" />
)}
</CardContent> </CardContent>
</Card> </Card>
); );
+22 -20
View File
@@ -1,32 +1,34 @@
'use client';
import { useEffect, useState } from 'react';
import AccountStatus from './accountStatus'; import AccountStatus from './accountStatus';
import Engagement from './engagement'; import Engagement from './engagement';
import Ideas from './ideas'; import Ideas from './ideas';
import RecentPosts from './recentPosts'; import RecentPosts from './recentPosts';
import App from '@/components/app'; import App from '@/components/app';
import { Calendar } from '@/components/ui/calendar'; import { Calendar } from '@/components/ui/calendar';
import { cookies } from 'next/headers';
import axios from 'axios'; import axios from 'axios';
import { redirect } from 'next/navigation'; import { useRouter } from 'next/navigation';
async function getSession(sessionId: string) { export default function Dashboard() {
try { const [data, setData] = useState({
return ( engagement: null,
await axios.get(`http://localhost:3000/api/session/?id=${sessionId}`) ideas: [],
).data.dashboard; accounts: [],
} catch { posts: [],
redirect('/login'); });
} const router = useRouter();
}
export default async function Dashboard() { useEffect(() => {
const cookieStore = await cookies(); axios
const sessionId = cookieStore.get('session_id')?.value || ''; .get('/api/session/')
.then((res) => {
const data = await getSession(sessionId); setData(res.data.dashboard);
})
if (!data) { .catch(() => {
return ''; router.push('/login');
} });
}, []);
return ( return (
<App> <App>
+10 -4
View File
@@ -18,10 +18,16 @@ export default function Login() {
const handleLogin = async () => { const handleLogin = async () => {
try { try {
const { sessionId } = ( const { sessionId } = (
await axios.post('/api/session/', { await axios.post(
email, '/api/session/',
password, {
}) email,
password,
},
{
withCredentials: true,
}
)
).data; ).data;
router.replace('/dashboard'); router.replace('/dashboard');
+1 -10
View File
@@ -1,14 +1,5 @@
import { cookies } from 'next/headers';
import { redirect } from 'next/navigation'; import { redirect } from 'next/navigation';
export default async function Home() { export default async function Home() {
const cookieStore = await cookies(); redirect('/dashboard');
const sessionId = cookieStore.get('session_id');
if (sessionId) {
redirect('/dashboard');
} else {
redirect('/login');
}
return 'redirecting...';
} }
-2
View File
@@ -3,7 +3,6 @@ Request types
*/ */
export interface PostRequest { export interface PostRequest {
sessionId: string;
content: string; content: string;
platforms: string[]; platforms: string[];
} }
@@ -14,7 +13,6 @@ export interface ScheduleRequest extends PostRequest {
export interface ScheduleRemoveRequest { export interface ScheduleRemoveRequest {
schedule: string; schedule: string;
id: string;
} }
/* /*