Many Changes
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
'use client'
|
||||
|
||||
import { authenticate } from '@/app/lib/actions'
|
||||
import { serverAttemptAuthenticateUser } from '@/app/lib/actions'
|
||||
import { useFormState, useFormStatus } from "react-dom";
|
||||
import { cookies } from 'next/headers';
|
||||
|
||||
|
||||
export default function Page(state:any) {
|
||||
const [loginResult, dispatch] = useFormState(authenticate, undefined)
|
||||
const [loginResult, dispatch] = useFormState(serverAttemptAuthenticateUser, undefined)
|
||||
console.log(dispatch);
|
||||
|
||||
console.log(state);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import AdminPanel from "@/components/admin/adminPanel";
|
||||
import AuthHandler from "@/components/admin/authHandler";
|
||||
import AdminPanel from "@/components/client/admin/adminPanel";
|
||||
import AuthHandler from "@/components/server/admin/authHandler";
|
||||
import { cookies } from "next/headers";
|
||||
|
||||
|
||||
|
||||
@@ -14,17 +14,10 @@ export async function GET(request:Request, { params }: {params:{slug: string}}){
|
||||
// @ts-ignore
|
||||
cookies().set('name', 'lee');
|
||||
return Response.json({
|
||||
"a": "lorem",
|
||||
"b": params
|
||||
"params": params
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// export default async function handler(req:NextApiRequest, res:NextApiResponse) {
|
||||
// await MPost.sync();
|
||||
// switch (req.method) {
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
'use server'
|
||||
|
||||
import { Model } from "sequelize";
|
||||
import { cookies } from "next/headers";
|
||||
|
||||
import { Auth, Post, User } from "@/model/sequelize/NewModels";
|
||||
|
||||
|
||||
import { APIError} from "@/api/error"
|
||||
import { UserAuth, parseBasicAuth, getAssociatedUser } from "@/api/user"
|
||||
import { Auth, User } from "@/model/Models";
|
||||
|
||||
|
||||
async function tryAuth(request:Request){
|
||||
@@ -31,15 +28,24 @@ async function tryAuth(request:Request){
|
||||
user_id: user.id,
|
||||
})
|
||||
|
||||
console.log('ok');
|
||||
const foundAuth = await Auth.findOne({
|
||||
include: 'user',
|
||||
include: {
|
||||
model: User,
|
||||
as: 'user'
|
||||
},
|
||||
where: {
|
||||
user_id: user.id
|
||||
}
|
||||
})
|
||||
console.log('ok2');
|
||||
|
||||
if(!foundAuth)
|
||||
return new Response("error",{status:500});
|
||||
|
||||
const usr = foundAuth.user;
|
||||
|
||||
|
||||
|
||||
const authUser = await authentication.getUser();
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
'use server'
|
||||
|
||||
import { Model } from "sequelize";
|
||||
import { Model } from "@sequelize/core";
|
||||
import { cookies } from "next/headers";
|
||||
|
||||
import { Auth, Post, User } from "@/model/sequelize/NewModels";
|
||||
|
||||
import { Auth } from "@/model/Models";
|
||||
|
||||
|
||||
import { APIError} from "@/api/error"
|
||||
@@ -23,9 +24,13 @@ async function tryAuth(request:Request){
|
||||
console.log(koek);
|
||||
const auth = JSON.parse(koek.value);
|
||||
|
||||
const authentication = await Auth.findOne( { include: 'user', where: {token:auth.token} })
|
||||
|
||||
const authentication = await Auth.findOne( { include: {
|
||||
association: Auth.associations.user
|
||||
}, where: { token:auth.token } })
|
||||
|
||||
|
||||
|
||||
if(!authentication)
|
||||
return new Response("unauthorized: invalid token",{status:403});
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use server'
|
||||
|
||||
import { APIError } from "@/api/error";
|
||||
import { Post } from "@/model/sequelize/NewModels";
|
||||
import { Post } from "@/model/Models";
|
||||
|
||||
|
||||
export async function tryFetchPost(request:Request, { params }: {params:{slug: string}}){
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
'use server'
|
||||
|
||||
import { APIError } from "@/api/error";
|
||||
import { Auth, Post, User } from "@/model/Models";
|
||||
import { Auth, Post, PostTag, Tag, User } from "@/model/Models";
|
||||
import { cookies } from "next/headers";
|
||||
import { where } from "sequelize";
|
||||
|
||||
|
||||
|
||||
async function tryCreatePost(request: Request) {
|
||||
|
||||
// Make sure the DB is ready
|
||||
await PostTag.sync();
|
||||
await Tag.sync();
|
||||
await Post.sync();
|
||||
|
||||
// Prepare data
|
||||
@@ -24,7 +25,7 @@ async function tryCreatePost(request: Request) {
|
||||
const authObject = JSON.parse(cookieJSON);
|
||||
|
||||
// Fetch User Auth from the database
|
||||
const auth = await Auth.findOne({ include: 'user', where: { token: authObject.token } });
|
||||
const auth:any = await Auth.findOne({ include: 'user', where: { token: authObject.token } });
|
||||
|
||||
// Sanity check the auth and associated user
|
||||
if (!auth || !auth.user) throw new APIError({ status: 401, responseText: "Authentication Error" });
|
||||
@@ -35,6 +36,7 @@ async function tryCreatePost(request: Request) {
|
||||
if (!requestBody.title) throw new APIError({ status: 500, responseText: "Missing post title" });
|
||||
if (!requestBody.content) throw new APIError({ status: 500, responseText: "Missing post content" });
|
||||
if (!user.id) throw new APIError({ status: 500, responseText: "Missing user id" });
|
||||
if (!user.perms || !user.perms.isAdmin) throw new APIError({ status: 401, responseText: "Unauthorized" });
|
||||
|
||||
// Create a new Post in the database
|
||||
const post = await Post.create(
|
||||
@@ -42,8 +44,11 @@ async function tryCreatePost(request: Request) {
|
||||
content: requestBody.content,
|
||||
user_id: user.id,
|
||||
title: requestBody.title,
|
||||
date: Date.now()
|
||||
},{include: "user"})
|
||||
},{
|
||||
include: {
|
||||
association: Post.associations.user
|
||||
}
|
||||
}).then(post=>post.reload())
|
||||
// // Find the post (Unneeded but nice to check)
|
||||
// const foundPost = await Post.findOne({
|
||||
// include: "user",
|
||||
@@ -52,7 +57,7 @@ async function tryCreatePost(request: Request) {
|
||||
// }
|
||||
// })
|
||||
|
||||
return new Response(JSON.stringify(Post), { status: 200 });
|
||||
return new Response(JSON.stringify(post), { status: 200 });
|
||||
|
||||
}
|
||||
|
||||
@@ -76,9 +81,12 @@ async function tryFetchPosts(request: Request) {
|
||||
await Post.sync();
|
||||
|
||||
const foundPosts = await Post.findAll({
|
||||
include: [{
|
||||
association: 'user',
|
||||
include: [
|
||||
{
|
||||
association: Post.associations.user,
|
||||
attributes: { exclude: ['password', 'createdAt', 'updatedAt'] }
|
||||
},{
|
||||
association: Post.associations.postTags
|
||||
}]
|
||||
});
|
||||
|
||||
|
||||
@@ -1,41 +1,48 @@
|
||||
'use server'
|
||||
|
||||
import { User, Auth, Post, UserPerms } from "@/model/sequelize/NewModels"
|
||||
|
||||
/* =================================================================================================
|
||||
*
|
||||
* Copyright 2024 Andreas Schaafsma
|
||||
* Purpose: Handle API requests that fetch or permute User data
|
||||
*
|
||||
* ================================================================================================= */
|
||||
|
||||
import { APIError } from "@/api/error";
|
||||
import { UserAuth } from "@/api/user";
|
||||
import { UserPerms, User, Auth } from "@/model/Models"; // Do not alter "unused" imports, they are required to perform the nescessairy includes on the User model
|
||||
import { hashPassword } from "@/util/Auth";
|
||||
|
||||
|
||||
|
||||
async function tryRegister(request:Request){
|
||||
// Attempt to register a new User
|
||||
async function attemptRegister(request:Request){
|
||||
|
||||
// Sync User model
|
||||
User.sync();
|
||||
|
||||
// Get request body
|
||||
const requestBody:Partial<UserAuth> = await request.json();
|
||||
|
||||
// Handle edgecases
|
||||
if(!requestBody) throw new APIError({status:500,responseText: "Request Body is Empty"})
|
||||
if(!requestBody.username) throw new APIError({status:500,responseText: "No username specified"})
|
||||
if(!requestBody.password) throw new APIError({status:500,responseText: "No password specified"})
|
||||
|
||||
// Try to get user from database
|
||||
const dbUser = await User.findOne({where:{username:requestBody.username}});
|
||||
|
||||
// If it exists we throw an error
|
||||
if(dbUser) throw new APIError({status:500,responseText: "Username unavailable, try another"});
|
||||
|
||||
const hash = await hashPassword(requestBody.password);
|
||||
// Hash the password and create a new user in the database
|
||||
const user = await User.create({
|
||||
username: requestBody.username,
|
||||
password: hash,
|
||||
password: await hashPassword(requestBody.password),
|
||||
perms:{
|
||||
isAdmin: false
|
||||
}
|
||||
|
||||
},
|
||||
{
|
||||
include: [{
|
||||
association: 'perms'
|
||||
association: User.associations.perms
|
||||
}]
|
||||
})
|
||||
|
||||
}).then(user=>user.reload());
|
||||
// Return the HTTP response
|
||||
return new Response(
|
||||
JSON.stringify(
|
||||
{
|
||||
@@ -52,7 +59,7 @@ async function tryRegister(request:Request){
|
||||
|
||||
export async function POST(request:Request){
|
||||
try{
|
||||
return await tryRegister(request);
|
||||
return await attemptRegister(request);
|
||||
}
|
||||
catch(e){
|
||||
if (e instanceof APIError){
|
||||
@@ -65,23 +72,9 @@ export async function POST(request:Request){
|
||||
}
|
||||
}
|
||||
|
||||
async function tryGetUsers(request:Request){
|
||||
|
||||
const defaultScope:any = User.scope('defaultScope');
|
||||
|
||||
const mergedInclude = defaultScope.include ? [defaultScope.include] : [];
|
||||
mergedInclude.push({ association: 'authtokens' });
|
||||
|
||||
// const mergedInclude = [...defaultScope.include, { association: 'authtokens' }];
|
||||
|
||||
const users = await User.findAll(
|
||||
{
|
||||
attributes: defaultScope.attributes,
|
||||
include: mergedInclude,
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
async function attemptGetUsers(request:Request){
|
||||
// Get users with scopes applied
|
||||
const users = await User.withScope(['defaultScope','withPerms','withAuthtokens']).findAll();
|
||||
return new Response(
|
||||
JSON.stringify(
|
||||
{
|
||||
@@ -98,7 +91,7 @@ async function tryGetUsers(request:Request){
|
||||
|
||||
export async function GET(request:Request){
|
||||
try{
|
||||
return await tryGetUsers(request);
|
||||
return await attemptGetUsers(request);
|
||||
}
|
||||
catch(e){
|
||||
if (e instanceof APIError){
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
import Header from "@/components/header";
|
||||
import PageContainer from "@/components/page-container";
|
||||
import Navbar from "@/components/navbar";
|
||||
import Sidebar from "@/components/sidebar";
|
||||
import Article from "@/components/news/article";
|
||||
import ArticlePreview from "@/components/news/article-preview"
|
||||
import Header from "@/components/shared/header";
|
||||
import PageContainer from "@/components/shared/page-container";
|
||||
import Navbar from "@/components/shared/navbar";
|
||||
import Sidebar from "@/components/shared/sidebar";
|
||||
import Article from "@/components/shared/news/article";
|
||||
import ArticlePreview from "@/components/shared/news/article-preview"
|
||||
|
||||
import ReactDOM from "react";
|
||||
|
||||
import "/public/global.css"
|
||||
import "@/app/index.css"
|
||||
import { Post, User } from "@/model/sequelize/NewModels";
|
||||
import { Attributes } from "sequelize";
|
||||
|
||||
import { Post } from "@/model/Post";
|
||||
import { Attributes } from "@sequelize/core";
|
||||
import { DeepPartial } from "@/util/DeepPartial";
|
||||
|
||||
|
||||
type DeepPartial<T> = T extends object ? {
|
||||
[P in keyof T]?: DeepPartial<T[P]>;
|
||||
} : T;
|
||||
|
||||
async function getData(slug:string):Promise<DeepPartial<Post>> {
|
||||
async function getData(slug:string):Promise<Attributes<Post>> {
|
||||
// Get all posts from the API
|
||||
const res = await fetch(`http://localhost:3000/api/post/${slug}`);
|
||||
// The return value is *not* serialized
|
||||
@@ -31,7 +31,7 @@ async function getData(slug:string):Promise<DeepPartial<Post>> {
|
||||
|
||||
export default async function Page({ params }: {params: {slug:string}}) {
|
||||
const { slug } = params;
|
||||
const post:DeepPartial<Attributes<Post>> = await getData(slug);
|
||||
const post:Attributes<Post> = await getData(slug);
|
||||
console.log(post);
|
||||
|
||||
|
||||
|
||||
@@ -5,27 +5,30 @@ import { constructAPIUrl } from "@/util/Utils"
|
||||
import { cookies } from "next/headers"
|
||||
import { parseSetCookie } from "@/util/parseSetCookie";
|
||||
import makeFetchCookie from 'fetch-cookie';
|
||||
import fetchCookie from "fetch-cookie";
|
||||
|
||||
type LoginReturn = {
|
||||
cookie?:unknown,
|
||||
errorMessage?:string;
|
||||
}
|
||||
|
||||
async function signIn(method:string,b:FormData):Promise<LoginReturn|null>
|
||||
async function attemptAPILogin(method:string,b:FormData):Promise<LoginReturn|null>
|
||||
{
|
||||
console.log("form data:");
|
||||
console.log(b);
|
||||
|
||||
if(!b || !b.get('input_username') || !b.get('input_password')) return null;
|
||||
let headers:Headers = new Headers();
|
||||
const fetchCookie = makeFetchCookie(fetch)
|
||||
headers.set('Authorization', 'Basic ' + Buffer.from(b.get('input_username') + ":" + b.get('input_password')).toString('base64'));
|
||||
let res = await fetchCookie(constructAPIUrl("auth"), {
|
||||
const { CookieJar, Cookie } = fetchCookie.toughCookie;
|
||||
const cj = new CookieJar()
|
||||
const fetchKoek = makeFetchCookie(fetch, cj);
|
||||
// Set Basic Auth
|
||||
headers.set('Authorization', `Basic ${Buffer.from(`${b.get('input_username')}:${b.get('input_password')}`).toString('base64')}`);
|
||||
let res = await fetchKoek(constructAPIUrl("auth"), {
|
||||
method:'POST',
|
||||
credentials: 'include',
|
||||
headers:headers,
|
||||
});
|
||||
|
||||
console.log(cj.store.idx['localhost']['/']);
|
||||
// if(res.headers.get('set-coo')) console.log(res.headers['set-cookie'])
|
||||
let koek = res.headers.getSetCookie();
|
||||
// console.log("api koek:" + koek.map((k)=>decodeURIComponent(k)));
|
||||
@@ -40,11 +43,11 @@ async function signIn(method:string,b:FormData):Promise<LoginReturn|null>
|
||||
// console.log(koek);
|
||||
}
|
||||
|
||||
export async function authenticate(_currentState: unknown, formData: FormData):Promise<LoginReturn|null>
|
||||
export async function serverAttemptAuthenticateUser(_currentState: unknown, formData: FormData):Promise<LoginReturn|null>
|
||||
{
|
||||
console.log("action triggered")
|
||||
try {
|
||||
const signInStatus = await signIn('credentials', formData)
|
||||
const signInStatus = await attemptAPILogin('credentials', formData)
|
||||
return signInStatus;
|
||||
} catch (error:any) {
|
||||
if (error) {
|
||||
@@ -62,10 +65,9 @@ export async function authenticate(_currentState: unknown, formData: FormData):P
|
||||
throw error
|
||||
}
|
||||
}
|
||||
export async function koekValid(koek:string):Promise<boolean>
|
||||
{
|
||||
|
||||
|
||||
export async function serverValidateSessionCookie(koek:string):Promise<boolean>
|
||||
{
|
||||
const validateSession = await fetch(constructAPIUrl("auth/validate"),{
|
||||
method:"POST",
|
||||
headers:{
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import Header from "@/components/header";
|
||||
import PageContainer from "@/components/page-container";
|
||||
import Navbar from "@/components/navbar";
|
||||
import Sidebar from "@/components/sidebar";
|
||||
import ArticlePreview from "@/components/news/article-preview"
|
||||
import Header from "@/components/shared/header";
|
||||
import PageContainer from "@/components/shared/page-container";
|
||||
import Navbar from "@/components/shared/navbar";
|
||||
import Sidebar from "@/components/shared/sidebar";
|
||||
import ArticlePreview from "@/components/shared/news/article-preview"
|
||||
import ReactDOM from "react";
|
||||
import "/public/global.css"
|
||||
import "./index.css"
|
||||
import { Post, PostAttributes } from "@/model/sequelize/NewModels";
|
||||
import { Post } from "@/model/Post";
|
||||
import { constructAPIUrl } from "@/util/Utils";
|
||||
import Link from "next/link";
|
||||
import { Attributes } from "@sequelize/core";
|
||||
|
||||
type DeepPartial<T> = T extends object ? {
|
||||
[P in keyof T]?: DeepPartial<T[P]>;
|
||||
@@ -18,7 +19,7 @@ export default async function Test() {
|
||||
|
||||
const response = await fetch(constructAPIUrl('post'));
|
||||
|
||||
const articles:Array<DeepPartial<PostAttributes>> = await response.json();
|
||||
const articles:Array<Attributes<Post>> = await response.json();
|
||||
|
||||
return <div className={`root`}>
|
||||
<Header/>
|
||||
@@ -32,9 +33,8 @@ export default async function Test() {
|
||||
</Sidebar> */}
|
||||
<main>
|
||||
{articles.map((article, i) => {
|
||||
console.log("Entered");
|
||||
// Return the element. Also pass key
|
||||
return (<ArticlePreview id={article?.id?.toString()} content={article?.content} title={article?.title}></ArticlePreview>)
|
||||
return (<ArticlePreview key={article?.id} id={article?.id?.toString()} content={article?.content} title={article?.title}></ArticlePreview>)
|
||||
})}
|
||||
</main>
|
||||
</PageContainer>
|
||||
|
||||
@@ -1,17 +1,30 @@
|
||||
import Header from "@/components/header";
|
||||
import PageContainer from "@/components/page-container";
|
||||
import Navbar from "@/components/navbar";
|
||||
import Sidebar from "@/components/sidebar";
|
||||
import ArticlePreview from "@/components/news/article-preview"
|
||||
import ReactDOM from "react";
|
||||
// import components
|
||||
import Header from "@/components/shared/header";
|
||||
import PageContainer from "@/components/shared/page-container";
|
||||
import Navbar from "@/components/shared/navbar";
|
||||
import Sidebar from "@/components/shared/sidebar";
|
||||
import ArticlePreview from "@/components/shared/news/article-preview"
|
||||
// import styles
|
||||
import "public/global.css"
|
||||
import "@/app/index.css"
|
||||
// import other shit
|
||||
import ReactDOM, { ReactNode } from "react";
|
||||
|
||||
type Props = {
|
||||
children?: ReactNode
|
||||
}
|
||||
|
||||
|
||||
export default function Page() {
|
||||
return <div className={`root`}>
|
||||
<Header/>
|
||||
<Navbar/>
|
||||
|
||||
export default function Page(props: Props) {
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div className={`root`}>
|
||||
<Header />
|
||||
<Navbar />
|
||||
<PageContainer>
|
||||
<Sidebar>
|
||||
<h1>
|
||||
@@ -20,10 +33,10 @@ export default function Page() {
|
||||
<ul><li>filter 1</li><li>filter 2</li><li>filter 3</li></ul>
|
||||
</Sidebar>
|
||||
<main>
|
||||
<ArticlePreview/>
|
||||
<ArticlePreview/>
|
||||
<ArticlePreview/>
|
||||
<ArticlePreview />
|
||||
<ArticlePreview />
|
||||
<ArticlePreview />
|
||||
</main>
|
||||
</PageContainer>
|
||||
</div>;
|
||||
</div>);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import Header from "@/components/header";
|
||||
import PageContainer from "@/components/page-container";
|
||||
import PageContainer from "@/components/shared/page-container";
|
||||
import Navbar from "@/components/navbar";
|
||||
import Sidebar from "@/components/sidebar";
|
||||
import Sidebar from "@/components/shared/sidebar";
|
||||
import ArticlePreview from "@/components/news/article-preview"
|
||||
import ReactDOM from "react";
|
||||
import "public/global.css"
|
||||
|
||||
Reference in New Issue
Block a user