Yea
This commit is contained in:
parent
838c2df336
commit
b1eb3cb9a6
23
config/config.json
Normal file
23
config/config.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"development": {
|
||||||
|
"username": "root",
|
||||||
|
"password": null,
|
||||||
|
"database": "database_development",
|
||||||
|
"host": "127.0.0.1",
|
||||||
|
"dialect": "sqlite"
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
"username": "root",
|
||||||
|
"password": null,
|
||||||
|
"database": "database_test",
|
||||||
|
"host": "127.0.0.1",
|
||||||
|
"dialect": "sqlite"
|
||||||
|
},
|
||||||
|
"production": {
|
||||||
|
"username": "root",
|
||||||
|
"password": null,
|
||||||
|
"database": "database_production",
|
||||||
|
"host": "127.0.0.1",
|
||||||
|
"dialect": "sqlite"
|
||||||
|
}
|
||||||
|
}
|
||||||
43
models/index.js
Normal file
43
models/index.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const Sequelize = require('sequelize');
|
||||||
|
const process = require('process');
|
||||||
|
const basename = path.basename(__filename);
|
||||||
|
const env = process.env.NODE_ENV || 'development';
|
||||||
|
const config = require(__dirname + '/../config/config.json')[env];
|
||||||
|
const db = {};
|
||||||
|
|
||||||
|
let sequelize;
|
||||||
|
if (config.use_env_variable) {
|
||||||
|
sequelize = new Sequelize(process.env[config.use_env_variable], config);
|
||||||
|
} else {
|
||||||
|
sequelize = new Sequelize(config.database, config.username, config.password, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
fs
|
||||||
|
.readdirSync(__dirname)
|
||||||
|
.filter(file => {
|
||||||
|
return (
|
||||||
|
file.indexOf('.') !== 0 &&
|
||||||
|
file !== basename &&
|
||||||
|
file.slice(-3) === '.js' &&
|
||||||
|
file.indexOf('.test.js') === -1
|
||||||
|
);
|
||||||
|
})
|
||||||
|
.forEach(file => {
|
||||||
|
const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
|
||||||
|
db[model.name] = model;
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.keys(db).forEach(modelName => {
|
||||||
|
if (db[modelName].associate) {
|
||||||
|
db[modelName].associate(db);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
db.sequelize = sequelize;
|
||||||
|
db.Sequelize = Sequelize;
|
||||||
|
|
||||||
|
module.exports = db;
|
||||||
@ -1,4 +1,8 @@
|
|||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {}
|
const nextConfig = {
|
||||||
|
experimental: {
|
||||||
|
serverComponentsExternalPackages: ['sequelize', 'sequelize-typescript'],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = nextConfig
|
module.exports = nextConfig
|
||||||
|
|||||||
3169
package-lock.json
generated
3169
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -24,14 +24,17 @@
|
|||||||
"mysql": "^2.18.1",
|
"mysql": "^2.18.1",
|
||||||
"mysql2": "^3.3.3",
|
"mysql2": "^3.3.3",
|
||||||
"next": "13.4.2",
|
"next": "13.4.2",
|
||||||
|
"pg-hstore": "^2.3.4",
|
||||||
"postcss": "8.4.23",
|
"postcss": "8.4.23",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-bootstrap": "^2.7.4",
|
"react-bootstrap": "^2.7.4",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"sequelize": "^6.32.0",
|
"sequelize": "^6.32.0",
|
||||||
"sqlite": "^4.2.1",
|
"sqlite": "^4.2.1",
|
||||||
"sqlite3": "^5.1.6",
|
|
||||||
"tailwindcss": "3.3.2",
|
"tailwindcss": "3.3.2",
|
||||||
"typescript": "5.0.4"
|
"typescript": "5.0.4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"sqlite3": "^5.1.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
src/api/error.ts
Normal file
16
src/api/error.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
|
||||||
|
type APIErrorMessage = {
|
||||||
|
status: number,
|
||||||
|
responseText: string
|
||||||
|
}
|
||||||
|
class APIError extends Error{
|
||||||
|
declare info:APIErrorMessage
|
||||||
|
constructor(message:APIErrorMessage) {
|
||||||
|
super(JSON.stringify(message))
|
||||||
|
this.info = message;
|
||||||
|
this.name = "AuthError"; // (different names for different built-in error classes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { APIError }
|
||||||
34
src/api/user.ts
Normal file
34
src/api/user.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
import { MUser } from "@/model/sequelize/User";
|
||||||
|
import { MAuth } from "@/model/sequelize/Auth";
|
||||||
|
|
||||||
|
import { validatePassword } from "@/util/Auth";
|
||||||
|
import { APIError } from "@/api/error";
|
||||||
|
|
||||||
|
export function parseBasicAuth(authb64:string):UserAuth
|
||||||
|
{
|
||||||
|
const authString:string = Buffer.from(authb64.split(" ")[1], "base64").toString("utf8");
|
||||||
|
var userAuth:UserAuth = {
|
||||||
|
username:authString.split(":")[0],
|
||||||
|
password:authString.split(":")[1]
|
||||||
|
};
|
||||||
|
return userAuth
|
||||||
|
}
|
||||||
|
|
||||||
|
export type UserAuth = {
|
||||||
|
username: string,
|
||||||
|
password: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getAssociatedUser(auth:UserAuth)
|
||||||
|
{
|
||||||
|
const username = auth.username;
|
||||||
|
let foundUser = await MUser.findOne({ where: {username: auth.username} });
|
||||||
|
|
||||||
|
if (!foundUser)
|
||||||
|
throw new APIError({status: 401, responseText:"Unauthorized: Invalid Username"});
|
||||||
|
|
||||||
|
if (!(await validatePassword(auth.password, foundUser.password)))
|
||||||
|
throw new APIError({status: 401, responseText:"Unauthorized: Invalid Password"});
|
||||||
|
|
||||||
|
return foundUser;
|
||||||
|
}
|
||||||
53
src/app/api2/[...slug]/route.ts
Normal file
53
src/app/api2/[...slug]/route.ts
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
'use server'
|
||||||
|
|
||||||
|
import { MPost } from "@/model/Models";
|
||||||
|
import { cookies } from "next/headers";
|
||||||
|
|
||||||
|
|
||||||
|
export async function GET(request:Request, { params }: {params:{slug: string}}){
|
||||||
|
console.log(request);
|
||||||
|
const url:NextURL = request.url;
|
||||||
|
console.log(url);
|
||||||
|
console.log(request);
|
||||||
|
console.log(params);
|
||||||
|
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
cookies().set('name', 'lee');
|
||||||
|
return Response.json({
|
||||||
|
"a": "kanker",
|
||||||
|
"b": params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// export default async function handler(req:NextApiRequest, res:NextApiResponse) {
|
||||||
|
// await MPost.sync();
|
||||||
|
// switch (req.method) {
|
||||||
|
// case 'GET':
|
||||||
|
// const posts = await MPost.findAll();
|
||||||
|
// res.status(200).json(posts);
|
||||||
|
// break;
|
||||||
|
// case 'POST':
|
||||||
|
// try {
|
||||||
|
// const post = await MPost.create({
|
||||||
|
// title: req.body.title,
|
||||||
|
// content: req.body.content,
|
||||||
|
// createdAt: new Date(),
|
||||||
|
// updatedAt: new Date(),
|
||||||
|
// },{ fields: ['title','content'] });
|
||||||
|
// const posts2 = await MPost.findAll();
|
||||||
|
// res.status(200).json(posts2);
|
||||||
|
// } catch (error) {
|
||||||
|
// console.log(error)
|
||||||
|
// }
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
78
src/app/api2/auth/route.ts
Normal file
78
src/app/api2/auth/route.ts
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
'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"
|
||||||
|
|
||||||
|
|
||||||
|
async function tryAuth(request:Request){
|
||||||
|
|
||||||
|
// await User.sync();
|
||||||
|
await Auth.sync();
|
||||||
|
|
||||||
|
const auth:string|null = request.headers.get("authorization");
|
||||||
|
|
||||||
|
if(!auth){
|
||||||
|
return new Response("unauthorized",{status:403});
|
||||||
|
}
|
||||||
|
|
||||||
|
const userAuth = parseBasicAuth(auth);
|
||||||
|
const user = await getAssociatedUser(userAuth);
|
||||||
|
|
||||||
|
if (!user || !user.id)
|
||||||
|
return new Response("error",{status:500});
|
||||||
|
|
||||||
|
const authentication = await Auth.create({
|
||||||
|
user_id: user.id,
|
||||||
|
})
|
||||||
|
|
||||||
|
const foundAuth = await Auth.findOne({
|
||||||
|
include: 'user',
|
||||||
|
where: {
|
||||||
|
user_id: user.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if(!foundAuth)
|
||||||
|
return new Response("error",{status:500});
|
||||||
|
|
||||||
|
|
||||||
|
const kanker = await authentication.getUser();
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
cookies().set('auth', JSON.stringify(authentication));
|
||||||
|
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify(
|
||||||
|
{
|
||||||
|
credentials: userAuth,
|
||||||
|
auth: authentication,
|
||||||
|
kanker: kanker,
|
||||||
|
foundAuth: foundAuth
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
status: 200,
|
||||||
|
headers:{
|
||||||
|
"Content-Type": "text/JSON"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function POST(request:Request){
|
||||||
|
try{
|
||||||
|
return await tryAuth(request);
|
||||||
|
}
|
||||||
|
catch(e){
|
||||||
|
if (e instanceof APIError){
|
||||||
|
return new Response(e.info.responseText,{status:e.info.status});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
34
src/app/api2/post/[...slug]/route.ts
Normal file
34
src/app/api2/post/[...slug]/route.ts
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
'use server'
|
||||||
|
|
||||||
|
import { APIError } from "@/api/error";
|
||||||
|
import { Post } from "@/model/sequelize/NewModels";
|
||||||
|
|
||||||
|
|
||||||
|
export async function tryFetchPost(request:Request, { params }: {params:{slug: string}}){
|
||||||
|
await Post.sync();
|
||||||
|
|
||||||
|
const foundPost = await Post.findOne({include:'user',where:{id:params.slug}});
|
||||||
|
|
||||||
|
return new Response(JSON.stringify(foundPost),{
|
||||||
|
status: 200,
|
||||||
|
headers:{
|
||||||
|
"Content-Type": "text/JSON"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function GET(request:Request, { params }: {params:{slug: string}}){
|
||||||
|
try{
|
||||||
|
return await tryFetchPost(request, { params });
|
||||||
|
}
|
||||||
|
catch(e){
|
||||||
|
if (e instanceof APIError){
|
||||||
|
return new Response(e.info.responseText,{status:e.info.status});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
104
src/app/api2/post/route.ts
Normal file
104
src/app/api2/post/route.ts
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
'use server'
|
||||||
|
|
||||||
|
import { APIError } from "@/api/error";
|
||||||
|
import { Auth, Post, User } from "@/model/sequelize/NewModels";
|
||||||
|
import { cookies } from "next/headers";
|
||||||
|
import { where } from "sequelize";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async function tryCreatePost(request:Request){
|
||||||
|
await Post.sync();
|
||||||
|
|
||||||
|
|
||||||
|
const requestBody = await request.json();
|
||||||
|
|
||||||
|
const authCookie = await cookies().get("auth");
|
||||||
|
|
||||||
|
if(!authCookie || !authCookie.value) throw new APIError({status:500,responseText: "missing auth cookie"});
|
||||||
|
|
||||||
|
const cookieJSON = authCookie.value;
|
||||||
|
|
||||||
|
const authObject = JSON.parse(cookieJSON);
|
||||||
|
|
||||||
|
const auth = await Auth.findOne({include: 'user', where:{token: authObject.token}});
|
||||||
|
|
||||||
|
|
||||||
|
if(!auth || !auth.user) throw new APIError({status:401,responseText: "Authentication Error"});
|
||||||
|
|
||||||
|
const user = auth.user;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// return new Response(JSON.stringify({auth,user}),{status:200});
|
||||||
|
|
||||||
|
|
||||||
|
if (!requestBody) throw new APIError({status:500,responseText: "Empty request body"});
|
||||||
|
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 (!requestBody.user_id) throw new APIError({status:500,responseText: "Missing user id"});
|
||||||
|
|
||||||
|
const post = await Post.create({
|
||||||
|
content:requestBody.content,
|
||||||
|
user_id:user.id,
|
||||||
|
title:requestBody.title,
|
||||||
|
date:Date.now()
|
||||||
|
})
|
||||||
|
|
||||||
|
const foundPost = await Post.findOne({
|
||||||
|
include:"user",
|
||||||
|
where:{
|
||||||
|
id:post.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
return new Response(JSON.stringify(foundPost),{status:200});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function POST(request:Request){
|
||||||
|
try{
|
||||||
|
return await tryCreatePost(request);
|
||||||
|
}
|
||||||
|
catch(e){
|
||||||
|
if (e instanceof APIError){
|
||||||
|
return new Response(e.info.responseText,{status:e.info.status});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function tryFetchPosts(request:Request){
|
||||||
|
|
||||||
|
await Post.sync();
|
||||||
|
|
||||||
|
const foundPosts = await Post.findAll({
|
||||||
|
include: [{
|
||||||
|
association: 'user',
|
||||||
|
attributes:{exclude:['password','createdAt','updatedAt']}
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
return new Response(JSON.stringify(foundPosts),{status:200});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export async function GET(request:Request){
|
||||||
|
try{
|
||||||
|
return await tryFetchPosts(request);
|
||||||
|
}
|
||||||
|
catch(e){
|
||||||
|
if (e instanceof APIError){
|
||||||
|
return new Response(e.info.responseText,{status:e.info.status});
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
91
src/app/api2/user/route.ts
Normal file
91
src/app/api2/user/route.ts
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
'use server'
|
||||||
|
|
||||||
|
import { User, Auth, Post } from "@/model/sequelize/NewModels"
|
||||||
|
import { APIError } from "@/api/error";
|
||||||
|
import { UserAuth } from "@/api/user";
|
||||||
|
import { hashPassword } from "@/util/Auth";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async function tryRegister(request:Request){
|
||||||
|
|
||||||
|
User.sync();
|
||||||
|
|
||||||
|
const requestBody:Partial<UserAuth> = await request.json();
|
||||||
|
|
||||||
|
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"})
|
||||||
|
|
||||||
|
const dbUser = await User.findOne({where:{username:requestBody.username}});
|
||||||
|
|
||||||
|
if(dbUser) throw new APIError({status:500,responseText: "Username unavailable, try another"});
|
||||||
|
|
||||||
|
const hash = await hashPassword(requestBody.password);
|
||||||
|
const user = await User.create({
|
||||||
|
username: requestBody.username,
|
||||||
|
password: hash
|
||||||
|
})
|
||||||
|
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify(
|
||||||
|
{
|
||||||
|
user: user
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
status: 200,
|
||||||
|
headers:{
|
||||||
|
"Content-Type": "text/JSON"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function POST(request:Request){
|
||||||
|
try{
|
||||||
|
return await tryRegister(request);
|
||||||
|
}
|
||||||
|
catch(e){
|
||||||
|
if (e instanceof APIError){
|
||||||
|
return new Response(e.info.responseText,{status:e.info.status});
|
||||||
|
console.log("responded")
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function tryGetUsers(request:Request){
|
||||||
|
|
||||||
|
const users = await User.findAll({include: "authtokens"});
|
||||||
|
|
||||||
|
|
||||||
|
return new Response(
|
||||||
|
JSON.stringify(
|
||||||
|
{
|
||||||
|
users: users
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
status: 200,
|
||||||
|
headers:{
|
||||||
|
"Content-Type": "text/JSON"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function GET(request:Request){
|
||||||
|
try{
|
||||||
|
return await tryGetUsers(request);
|
||||||
|
}
|
||||||
|
catch(e){
|
||||||
|
if (e instanceof APIError){
|
||||||
|
return new Response(e.info.responseText,{status:e.info.status});
|
||||||
|
console.log("responded")
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -7,20 +7,21 @@ import ArticlePreview from "@/components/news/article-preview"
|
|||||||
import ReactDOM from "react";
|
import ReactDOM from "react";
|
||||||
import "public/global.css"
|
import "public/global.css"
|
||||||
import "@/app/index.css"
|
import "@/app/index.css"
|
||||||
|
import { Post, User } from "@/model/sequelize/NewModels";
|
||||||
|
import { Attributes } from "sequelize";
|
||||||
|
|
||||||
|
|
||||||
type Post = {
|
type DeepPartial<T> = T extends object ? {
|
||||||
id: Number,
|
[P in keyof T]?: DeepPartial<T[P]>;
|
||||||
title: String,
|
} : T;
|
||||||
content: String
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getData(slug:String):Promise<Array<any>> {
|
async function getData(slug:string):Promise<DeepPartial<Post>> {
|
||||||
// Get all posts from the API
|
// Get all posts from the API
|
||||||
const res = await fetch(`http://localhost:3000/api/post/${slug}`);
|
const res = await fetch(`http://localhost:3000/api2/post/${slug}`);
|
||||||
// The return value is *not* serialized
|
// The return value is *not* serialized
|
||||||
// You can return Date, Map, Set, etc.
|
// You can return Date, Map, Set, etc.
|
||||||
// Recommendation: handle errors
|
// Recommendation: handle errors
|
||||||
|
console.log(res);
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
// This will activate the closest `error.js` Error Boundary
|
// This will activate the closest `error.js` Error Boundary
|
||||||
throw new Error('Failed to fetch data');
|
throw new Error('Failed to fetch data');
|
||||||
@ -28,11 +29,12 @@ async function getData(slug:String):Promise<Array<any>> {
|
|||||||
return res.json();
|
return res.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function Page({ params }) {
|
export default async function Page({ params }: {params: {slug:string}}) {
|
||||||
const { slug } = params;
|
const { slug } = params;
|
||||||
const post = ((await getData(slug))[0]);
|
const post:DeepPartial<Attributes<Post>> = await getData(slug);
|
||||||
console.log(post);
|
console.log(post);
|
||||||
|
|
||||||
|
|
||||||
return <div className={`root`}>
|
return <div className={`root`}>
|
||||||
<Header />
|
<Header />
|
||||||
<Navbar />
|
<Navbar />
|
||||||
@ -44,7 +46,7 @@ export default async function Page({ params }) {
|
|||||||
<ul><li>filter 1</li><li>filter 2</li><li>filter 3</li></ul>
|
<ul><li>filter 1</li><li>filter 2</li><li>filter 3</li></ul>
|
||||||
</Sidebar>
|
</Sidebar>
|
||||||
<main>
|
<main>
|
||||||
<Article id={post.id} title={post.post.title} content={post.post.content}/>
|
<Article id={post?.id?.toString()} title={post?.title?.toString()} content={post?.content?.toString()}/>
|
||||||
</main>
|
</main>
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
</div>;
|
</div>;
|
||||||
@ -6,9 +6,18 @@ import ArticlePreview from "@/components/news/article-preview"
|
|||||||
import ReactDOM from "react";
|
import ReactDOM from "react";
|
||||||
import "public/global.css"
|
import "public/global.css"
|
||||||
import "./index.css"
|
import "./index.css"
|
||||||
|
import { Post } from "@/model/sequelize/NewModels";
|
||||||
|
|
||||||
|
type DeepPartial<T> = T extends object ? {
|
||||||
|
[P in keyof T]?: DeepPartial<T[P]>;
|
||||||
|
} : T;
|
||||||
|
|
||||||
|
export default async function Test() {
|
||||||
|
|
||||||
|
const response = await fetch("http://localhost:3000/api2/post/");
|
||||||
|
const articles:Array<DeepPartial<Post>> = await response.json();
|
||||||
|
|
||||||
|
|
||||||
export default function Test() {
|
|
||||||
return <div className={`root`}>
|
return <div className={`root`}>
|
||||||
<Header/>
|
<Header/>
|
||||||
<Navbar/>
|
<Navbar/>
|
||||||
@ -20,9 +29,11 @@ export default function Test() {
|
|||||||
<ul><li>filter 1</li><li>filter 2</li><li>filter 3</li></ul>
|
<ul><li>filter 1</li><li>filter 2</li><li>filter 3</li></ul>
|
||||||
</Sidebar>
|
</Sidebar>
|
||||||
<main>
|
<main>
|
||||||
<ArticlePreview/>
|
{articles.map((article, i) => {
|
||||||
<ArticlePreview/>
|
console.log("Entered");
|
||||||
<ArticlePreview/>
|
// Return the element. Also pass key
|
||||||
|
return (<ArticlePreview id={article?.id?.toString()} content={article?.content} title={article?.title}></ArticlePreview>)
|
||||||
|
})}
|
||||||
</main>
|
</main>
|
||||||
</PageContainer>
|
</PageContainer>
|
||||||
</div>;
|
</div>;
|
||||||
|
|||||||
@ -6,16 +6,14 @@ import { ReactNode } from "react"
|
|||||||
import { Style } from "util";
|
import { Style } from "util";
|
||||||
|
|
||||||
|
|
||||||
export default function ArticlePreview(params: { id: String, title: String, content: String, date?:String } ){
|
export default function ArticlePreview(params: { id: string|undefined, title: string|undefined, content: string|undefined, date?:string|undefined } ){
|
||||||
return <div className={styles.previewbox}>
|
return <div className={styles.previewbox}>
|
||||||
<div className={styles.imagecontainer}>
|
<div className={styles.imagecontainer}>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div className={styles.summary}>
|
<div className={styles.summary}>
|
||||||
<h2>Lorem Ipsum</h2><Tagbar/>
|
<h2>{params.title}</h2><Tagbar/>
|
||||||
<p>
|
<p>{params.content}</p>
|
||||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed vitae orci quis elit suscipit varius vitae sed sem. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
@ -4,7 +4,7 @@ import "@/app/index.css"
|
|||||||
import styles from "./article.module.css"
|
import styles from "./article.module.css"
|
||||||
|
|
||||||
|
|
||||||
export default function Article(params: { id: String, title: String, content: String, date?:String } ) {
|
export default function Article(params: { id: string|undefined, title: string|undefined, content: string|undefined, date?:string|undefined } ) {
|
||||||
return (
|
return (
|
||||||
<article id={`post-${params.id}`}>
|
<article id={`post-${params.id}`}>
|
||||||
<h1 className=".article-title">{params.title}</h1>
|
<h1 className=".article-title">{params.title}</h1>
|
||||||
|
|||||||
@ -1,56 +0,0 @@
|
|||||||
import Gens from "@/gens";
|
|
||||||
import { Sequelize, DataTypes, Association, UUIDV4 } from 'sequelize';
|
|
||||||
|
|
||||||
const sequelize = new Sequelize({
|
|
||||||
dialect: 'sqlite',
|
|
||||||
storage: 'db.sqlite'
|
|
||||||
});
|
|
||||||
export const MPost = sequelize.define('Post', {
|
|
||||||
id: {
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
primaryKey: true
|
|
||||||
},
|
|
||||||
title: DataTypes.STRING,
|
|
||||||
content: DataTypes.STRING,
|
|
||||||
// date: DataTypes.DATE,
|
|
||||||
});
|
|
||||||
export const MAuth = sequelize.define('Auth', {
|
|
||||||
id: {
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
primaryKey: true
|
|
||||||
},
|
|
||||||
token: {
|
|
||||||
type: DataTypes.UUID,
|
|
||||||
defaultValue: UUIDV4
|
|
||||||
},
|
|
||||||
user_id: {
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
key: "User"
|
|
||||||
}
|
|
||||||
// date: DataTypes.DATE,
|
|
||||||
});
|
|
||||||
export const MUser = sequelize.define('User', {
|
|
||||||
id: {
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
primaryKey: true
|
|
||||||
},
|
|
||||||
username: DataTypes.STRING,
|
|
||||||
password: DataTypes.STRING,
|
|
||||||
// date: DataTypes.DATE,
|
|
||||||
});
|
|
||||||
|
|
||||||
MAuth.hasOne(MUser)
|
|
||||||
|
|
||||||
|
|
||||||
export type Post = {
|
|
||||||
id: Number,
|
|
||||||
title: String,
|
|
||||||
content: String,
|
|
||||||
date?: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
export const postPlaceholder:Post = {
|
|
||||||
id: -1,
|
|
||||||
title: 'Lorem Ipsum',
|
|
||||||
content: Gens.loremipsum()
|
|
||||||
};
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
type Post = {
|
|
||||||
id: Number,
|
|
||||||
title: String,
|
|
||||||
content: String,
|
|
||||||
date?: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
export type { Post }
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
import { Sequelize, DataTypes, Optional, Model, UUIDV4 } from 'sequelize';
|
|
||||||
import { MPost } from '@/model/sequelize/Post';
|
|
||||||
const sequelize = new Sequelize({
|
|
||||||
dialect: 'sqlite',
|
|
||||||
storage: 'db.sqlite'
|
|
||||||
});
|
|
||||||
interface AttachmentAttributes{
|
|
||||||
id: string;
|
|
||||||
path: string;
|
|
||||||
post_id: number;
|
|
||||||
};
|
|
||||||
interface AttachmentCreationAttributes extends Optional<AttachmentAttributes, 'id'>{};
|
|
||||||
class AttachmentModel extends Model<AttachmentAttributes, AttachmentCreationAttributes>{
|
|
||||||
id:string = "";
|
|
||||||
path:string = "";
|
|
||||||
post_id:number|undefined;
|
|
||||||
createdAt?: Date;
|
|
||||||
updatedAt?: Date;
|
|
||||||
// declare title
|
|
||||||
}
|
|
||||||
export const MAttachment = sequelize.define<AttachmentModel>(
|
|
||||||
'Attachment',
|
|
||||||
{
|
|
||||||
id: {
|
|
||||||
allowNull: false,
|
|
||||||
autoIncrement: false,
|
|
||||||
type: DataTypes.UUID,
|
|
||||||
defaultValue: UUIDV4,
|
|
||||||
primaryKey: true,
|
|
||||||
unique: true,
|
|
||||||
},
|
|
||||||
path: {
|
|
||||||
type: DataTypes.STRING,
|
|
||||||
},
|
|
||||||
post_id: {
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
key: "Post"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
MAttachment.hasOne(MPost);
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
// import { Sequelize, DataTypes, Optional, Model, UUIDV4 } from 'sequelize';
|
|
||||||
import {
|
|
||||||
Association, DataTypes, HasManyAddAssociationMixin, HasManyCountAssociationsMixin,
|
|
||||||
HasManyCreateAssociationMixin, HasManyGetAssociationsMixin, HasManyHasAssociationMixin,
|
|
||||||
HasManySetAssociationsMixin, HasManyAddAssociationsMixin, HasManyHasAssociationsMixin,
|
|
||||||
HasManyRemoveAssociationMixin, HasManyRemoveAssociationsMixin, Model, ModelDefined, Optional,
|
|
||||||
Sequelize, InferAttributes, InferCreationAttributes, CreationOptional, NonAttribute, ForeignKey, BelongsTo, BelongsToGetAssociationMixin, UUIDV4, UUID
|
|
||||||
} from 'sequelize';
|
|
||||||
|
|
||||||
import { MUser, UserModel } from '@/model/sequelize/User';
|
|
||||||
const sequelize = new Sequelize({
|
|
||||||
dialect: 'sqlite',
|
|
||||||
storage: 'db.sqlite'
|
|
||||||
});
|
|
||||||
// interface AuthAttributes{
|
|
||||||
// id: number;
|
|
||||||
// token: string;
|
|
||||||
// user_id: number;
|
|
||||||
// };
|
|
||||||
// interface AuthCreationAttributes extends Optional<Optional<AuthAttributes, 'id'>,'token'> {};
|
|
||||||
// class AuthModel extends Model<AuthAttributes, AuthCreationAttributes>{
|
|
||||||
// createdAt?: Date;
|
|
||||||
// updatedAt?: Date;
|
|
||||||
// token: any;
|
|
||||||
// // declare title
|
|
||||||
// }
|
|
||||||
class AuthModel extends Model<InferAttributes<AuthModel, { omit: 'user' }>, InferCreationAttributes<AuthModel, { omit: 'user' }>> {
|
|
||||||
declare id: CreationOptional<number>;
|
|
||||||
declare token: CreationOptional<string>;
|
|
||||||
declare user_id: number;
|
|
||||||
declare getUser: BelongsToGetAssociationMixin<UserModel>;
|
|
||||||
declare user:NonAttribute<UserModel>;
|
|
||||||
}
|
|
||||||
export const MAuth = AuthModel.init(
|
|
||||||
{
|
|
||||||
id: {
|
|
||||||
allowNull: false,
|
|
||||||
autoIncrement: true,
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
primaryKey: true,
|
|
||||||
unique: true,
|
|
||||||
},
|
|
||||||
token: {
|
|
||||||
type: DataTypes.UUID,
|
|
||||||
defaultValue: UUIDV4
|
|
||||||
},
|
|
||||||
user_id: {
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
key: "User"
|
|
||||||
}
|
|
||||||
// date: DataTypes.DATE,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tableName: 'Auths',
|
|
||||||
sequelize // passing the `sequelize` instance is required
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
MAuth.belongsTo(MUser, {
|
|
||||||
foreignKey:'user_id',
|
|
||||||
targetKey:'id',
|
|
||||||
as: 'user'
|
|
||||||
})
|
|
||||||
|
|
||||||
MUser.hasMany(MAuth, {
|
|
||||||
sourceKey: 'id',
|
|
||||||
foreignKey: 'user_id',
|
|
||||||
as: 'authtokens' // this determines the name in `associations`!
|
|
||||||
});
|
|
||||||
// MAuth.belongsTo(MUser, { targetKey: 'id' });
|
|
||||||
// MAuth.sync();
|
|
||||||
|
|
||||||
export { AuthModel }
|
|
||||||
144
src/model/sequelize/NewModels.ts
Normal file
144
src/model/sequelize/NewModels.ts
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
import {
|
||||||
|
Association, DataTypes, HasManyAddAssociationMixin, HasManyCountAssociationsMixin,
|
||||||
|
HasManyCreateAssociationMixin, HasManyGetAssociationsMixin, HasManyHasAssociationMixin,
|
||||||
|
HasManySetAssociationsMixin, HasManyAddAssociationsMixin, HasManyHasAssociationsMixin,
|
||||||
|
HasManyRemoveAssociationMixin, HasManyRemoveAssociationsMixin, Model, ModelDefined, Optional,
|
||||||
|
Sequelize, InferAttributes, InferCreationAttributes, CreationOptional, NonAttribute, ForeignKey, BelongsTo, BelongsToGetAssociationMixin, UUIDV4, UUID,
|
||||||
|
VirtualDataType
|
||||||
|
} from 'sequelize';
|
||||||
|
|
||||||
|
|
||||||
|
const sequelize = new Sequelize({
|
||||||
|
dialect: 'sqlite',
|
||||||
|
storage: 'db.sqlite'
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
export class Auth extends Model<InferAttributes<Auth>, InferCreationAttributes<Auth>> {
|
||||||
|
declare id: CreationOptional<number>;
|
||||||
|
declare token: CreationOptional<string>;
|
||||||
|
declare user:NonAttribute<User>;
|
||||||
|
declare user_id:ForeignKey<User['id']>;
|
||||||
|
declare getUser: BelongsToGetAssociationMixin<User>;
|
||||||
|
declare static associations: {
|
||||||
|
user: Association<User, Auth>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Auth.init({
|
||||||
|
id: {
|
||||||
|
allowNull: false,
|
||||||
|
autoIncrement: true,
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
unique: true,
|
||||||
|
},
|
||||||
|
token: {
|
||||||
|
type: DataTypes.UUID,
|
||||||
|
defaultValue: UUIDV4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tableName: 'Auths',
|
||||||
|
sequelize // passing the `sequelize` instance is required
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
export class Post extends Model<InferAttributes<Post>, InferCreationAttributes<Post>> {
|
||||||
|
declare id: number|null;
|
||||||
|
declare title: string;
|
||||||
|
declare content: string;
|
||||||
|
declare date: number;
|
||||||
|
declare user:NonAttribute<User>;
|
||||||
|
declare user_id:ForeignKey<User['id']>;
|
||||||
|
declare getUser: BelongsToGetAssociationMixin<User>;
|
||||||
|
declare static associations: {
|
||||||
|
user: Association<User, Post>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Post.init(
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
allowNull: false,
|
||||||
|
autoIncrement: true,
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
unique: true,
|
||||||
|
},
|
||||||
|
content: {
|
||||||
|
type: DataTypes.STRING
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: DataTypes.STRING
|
||||||
|
},
|
||||||
|
date: {
|
||||||
|
type: DataTypes.DATE
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tableName: 'Posts',
|
||||||
|
sequelize // passing the `sequelize` instance is required
|
||||||
|
}
|
||||||
|
);
|
||||||
|
export class User extends Model<InferAttributes<User>, InferCreationAttributes<User>>{
|
||||||
|
declare id: number|null;
|
||||||
|
declare username: string;
|
||||||
|
declare password: string;
|
||||||
|
declare getAuthTokens:HasManyGetAssociationsMixin<Auth>;
|
||||||
|
declare getPosts:HasManyGetAssociationsMixin<Post>;
|
||||||
|
}
|
||||||
|
|
||||||
|
User.init(
|
||||||
|
{
|
||||||
|
id: {
|
||||||
|
allowNull: false,
|
||||||
|
autoIncrement: true,
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
primaryKey: true,
|
||||||
|
unique: true,
|
||||||
|
},
|
||||||
|
username: {
|
||||||
|
allowNull: false,
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
},
|
||||||
|
password: {
|
||||||
|
allowNull: false,
|
||||||
|
type: DataTypes.STRING,
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
{
|
||||||
|
defaultScope: {
|
||||||
|
attributes:{
|
||||||
|
exclude:['password']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
tableName: 'Users',
|
||||||
|
sequelize // passing the `sequelize` instance is required
|
||||||
|
}
|
||||||
|
);
|
||||||
|
User.scope
|
||||||
|
|
||||||
|
Auth.belongsTo(User, {
|
||||||
|
foreignKey:'user_id',
|
||||||
|
targetKey:'id',
|
||||||
|
as: 'user',
|
||||||
|
})
|
||||||
|
User.hasMany(Auth, {
|
||||||
|
sourceKey: 'id',
|
||||||
|
foreignKey: 'user_id',
|
||||||
|
as: 'authtokens' // this determines the name in `associations`!
|
||||||
|
});
|
||||||
|
Post.belongsTo(User, {
|
||||||
|
foreignKey:'user_id',
|
||||||
|
targetKey:'id',
|
||||||
|
as: 'user'
|
||||||
|
})
|
||||||
|
User.hasMany(Post, {
|
||||||
|
sourceKey: 'id',
|
||||||
|
foreignKey: 'user_id',
|
||||||
|
as: 'posts' // this determines the name in `associations`!
|
||||||
|
});
|
||||||
|
|
||||||
|
User.sync();
|
||||||
|
Auth.sync();
|
||||||
|
Post.sync();
|
||||||
@ -1,34 +0,0 @@
|
|||||||
import { Sequelize, DataTypes, Optional, Model } from 'sequelize';
|
|
||||||
import { MAttachment } from '@/model/sequelize/Attachment';
|
|
||||||
const sequelize = new Sequelize({
|
|
||||||
dialect: 'sqlite',
|
|
||||||
storage: 'db.sqlite'
|
|
||||||
});
|
|
||||||
interface PostAttributes{
|
|
||||||
id: number;
|
|
||||||
title: string;
|
|
||||||
content: string;
|
|
||||||
};
|
|
||||||
interface PostCreationAttributes extends Optional<PostAttributes, 'id'>{};
|
|
||||||
class PostModel extends Model<PostAttributes, PostCreationAttributes>{
|
|
||||||
username:string = "";
|
|
||||||
password:string = "";
|
|
||||||
createdAt?: Date;
|
|
||||||
updatedAt?: Date;
|
|
||||||
// declare title
|
|
||||||
}
|
|
||||||
export const MPost = sequelize.define<PostModel>(
|
|
||||||
'Post',
|
|
||||||
{
|
|
||||||
id: {
|
|
||||||
allowNull: false,
|
|
||||||
autoIncrement: true,
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
primaryKey: true,
|
|
||||||
unique: true,
|
|
||||||
},
|
|
||||||
title: DataTypes.STRING,
|
|
||||||
content: DataTypes.STRING,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
MPost.hasMany(MAttachment);
|
|
||||||
@ -1,73 +0,0 @@
|
|||||||
import { BelongsToGetAssociationMixin, UUIDV4 } from 'sequelize';
|
|
||||||
import {
|
|
||||||
Association, DataTypes, HasManyAddAssociationMixin, HasManyCountAssociationsMixin,
|
|
||||||
HasManyCreateAssociationMixin, HasManyGetAssociationsMixin, HasManyHasAssociationMixin,
|
|
||||||
HasManySetAssociationsMixin, HasManyAddAssociationsMixin, HasManyHasAssociationsMixin,
|
|
||||||
HasManyRemoveAssociationMixin, HasManyRemoveAssociationsMixin, Model, ModelDefined, Optional,
|
|
||||||
Sequelize, InferAttributes, InferCreationAttributes, CreationOptional, NonAttribute, ForeignKey,
|
|
||||||
} from 'sequelize';
|
|
||||||
import { UserModel } from '@/model/sequelize/User';
|
|
||||||
|
|
||||||
const sequelize = new Sequelize({
|
|
||||||
dialect: 'sqlite',
|
|
||||||
storage: 'db.sqlite'
|
|
||||||
});
|
|
||||||
class ResourceModel extends Model<InferAttributes<ResourceModel, { omit: 'owner' }>, InferCreationAttributes<ResourceModel, { omit: 'owner' }>>{
|
|
||||||
declare id: CreationOptional<string>;
|
|
||||||
declare path: string;
|
|
||||||
declare owner: NonAttribute<UserModel>;
|
|
||||||
declare getOwner: BelongsToGetAssociationMixin<UserModel>;
|
|
||||||
|
|
||||||
// user_id: number | undefined;
|
|
||||||
createdAt?: Date;
|
|
||||||
updatedAt?: Date;
|
|
||||||
// declare title
|
|
||||||
declare static associations: {
|
|
||||||
owner: Association<ResourceModel,UserModel>;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
ResourceModel.init({
|
|
||||||
id: {
|
|
||||||
allowNull: false,
|
|
||||||
autoIncrement: false,
|
|
||||||
type: DataTypes.UUID,
|
|
||||||
defaultValue: UUIDV4,
|
|
||||||
primaryKey: true,
|
|
||||||
unique: true,
|
|
||||||
},
|
|
||||||
path: {
|
|
||||||
type: DataTypes.STRING
|
|
||||||
},
|
|
||||||
createdAt: {
|
|
||||||
type: DataTypes.DATE
|
|
||||||
},
|
|
||||||
updatedAt: {
|
|
||||||
type: DataTypes.DATE
|
|
||||||
}
|
|
||||||
},{
|
|
||||||
sequelize,
|
|
||||||
tableName: 'Resource'
|
|
||||||
});
|
|
||||||
// export const MResource = sequelize.define<ResourceModel>(
|
|
||||||
// 'Resource',
|
|
||||||
// {
|
|
||||||
// id: {
|
|
||||||
// allowNull: false,
|
|
||||||
// autoIncrement: false,
|
|
||||||
// type: DataTypes.UUID,
|
|
||||||
// defaultValue: UUIDV4,
|
|
||||||
// primaryKey: true,
|
|
||||||
// unique: true,
|
|
||||||
// },
|
|
||||||
// path: {
|
|
||||||
// type: DataTypes.STRING,
|
|
||||||
// },
|
|
||||||
// user_id: {
|
|
||||||
// type: DataTypes.INTEGER,
|
|
||||||
// key: "User"
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
// UserModel.hasMany(MResource);
|
|
||||||
// ResourceModel.belongsTo(UserModel);
|
|
||||||
@ -1,60 +0,0 @@
|
|||||||
// import { Sequelize, DataTypes, Optional, Model } from 'sequelize';
|
|
||||||
import {
|
|
||||||
Association, DataTypes, HasManyAddAssociationMixin, HasManyCountAssociationsMixin,
|
|
||||||
HasManyCreateAssociationMixin, HasManyGetAssociationsMixin, HasManyHasAssociationMixin,
|
|
||||||
HasManySetAssociationsMixin, HasManyAddAssociationsMixin, HasManyHasAssociationsMixin,
|
|
||||||
HasManyRemoveAssociationMixin, HasManyRemoveAssociationsMixin, Model, ModelDefined, Optional,
|
|
||||||
Sequelize, InferAttributes, InferCreationAttributes, CreationOptional, NonAttribute, ForeignKey, BelongsTo, BelongsToGetAssociationMixin, UUIDV4, UUID
|
|
||||||
} from 'sequelize';
|
|
||||||
|
|
||||||
import { AuthModel } from '@/model/sequelize/Auth';
|
|
||||||
|
|
||||||
const sequelize = new Sequelize({
|
|
||||||
dialect: 'sqlite',
|
|
||||||
storage: 'db.sqlite'
|
|
||||||
});
|
|
||||||
// interface UserAttributes{
|
|
||||||
// id: number;
|
|
||||||
// username: string;
|
|
||||||
// password: string;
|
|
||||||
// };
|
|
||||||
// interface UserCreationAttributes extends Optional<UserAttributes, 'id'>{};
|
|
||||||
// export class UserModel extends Model<UserAttributes, UserCreationAttributes>{
|
|
||||||
// createdAt?: Date;
|
|
||||||
// updatedAt?: Date;
|
|
||||||
// username: string = "";
|
|
||||||
// password: string = "";
|
|
||||||
// id?:number;
|
|
||||||
// // declare title
|
|
||||||
// }
|
|
||||||
export class UserModel extends Model<InferAttributes<UserModel>, InferCreationAttributes<UserModel>>{
|
|
||||||
declare id: number|null;
|
|
||||||
declare username: string;
|
|
||||||
declare password: string;
|
|
||||||
declare getAuths:HasManyGetAssociationsMixin<AuthModel>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const MUser = UserModel.init(
|
|
||||||
{
|
|
||||||
id: {
|
|
||||||
allowNull: false,
|
|
||||||
autoIncrement: true,
|
|
||||||
type: DataTypes.INTEGER,
|
|
||||||
primaryKey: true,
|
|
||||||
unique: true,
|
|
||||||
},
|
|
||||||
username: {
|
|
||||||
allowNull: false,
|
|
||||||
type: DataTypes.STRING,
|
|
||||||
},
|
|
||||||
password: {
|
|
||||||
allowNull: false,
|
|
||||||
type: DataTypes.STRING,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tableName: 'Users',
|
|
||||||
sequelize // passing the `sequelize` instance is required
|
|
||||||
}
|
|
||||||
);
|
|
||||||
MUser.sync();
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
import mysql2, { Connection, RowDataPacket, OkPacket, QueryError } from "mysql2";
|
|
||||||
import { getConnection } from "@/db";
|
|
||||||
import { Post, postPlaceholder } from "@/model/Models";
|
|
||||||
import { getPosts, IPost } from "@/controller/Post";
|
|
||||||
import { NextApiRequest, NextApiResponse } from "next";
|
|
||||||
import { MPost } from "@/model/sequelize/Post";
|
|
||||||
import { MAttachment } from "@/model/sequelize/Attachment";
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
import { validatePassword, hashPassword } from "@/util/Auth";
|
|
||||||
|
|
||||||
|
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
||||||
if (req.method === 'Post') {
|
|
||||||
let getAuth = () => {
|
|
||||||
try {
|
|
||||||
if (req.headers.authorization === undefined) {
|
|
||||||
throw "Basic Auth is required";
|
|
||||||
}
|
|
||||||
const authString = Buffer.from(req.headers.authorization.split(" ")[1], "base64").toString("utf8");
|
|
||||||
return authString.split(":");
|
|
||||||
} catch (error) {
|
|
||||||
res.status(500).json(error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const auth = getAuth() || ["", ""];
|
|
||||||
console.log(auth);
|
|
||||||
const username = auth[0];
|
|
||||||
const password = auth[1];
|
|
||||||
// console.log(req.body);
|
|
||||||
await MUser.sync();
|
|
||||||
await MAuth.sync();
|
|
||||||
|
|
||||||
let user = await MUser.findOne({ where: { username: username } });
|
|
||||||
if (user == undefined) {
|
|
||||||
res.status(401).json("User does not exist");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(await validatePassword(password, user.password))) {
|
|
||||||
res.status(401).json("Invalid password");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let authtoken = await MAuth.findOne({ where: { user_id: user.id } });
|
|
||||||
if (authtoken == undefined) {
|
|
||||||
if (user.id != undefined) {
|
|
||||||
authtoken = await MAuth.create({ user_id: user.id });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
res.status(200).json(authtoken);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,115 +0,0 @@
|
|||||||
// import mysql2, { Connection, RowDataPacket, OkPacket, QueryError } from "mysql2";
|
|
||||||
import { getConnection } from "@/db";
|
|
||||||
// import { Post, postPlaceholder } from "@/model/Models";
|
|
||||||
import { getPosts, IPost } from "@/controller/Post";
|
|
||||||
import { NextApiRequest, NextApiResponse } from "next";
|
|
||||||
import { MPost } from "@/model/sequelize/Post";
|
|
||||||
import { MUser, UserModel } from "@/model/sequelize/User";
|
|
||||||
import { MAuth } from "@/model/sequelize/Auth";
|
|
||||||
import { cookies } from 'next/headers';
|
|
||||||
import { setCookie } from '@/util/Cookies';
|
|
||||||
|
|
||||||
import { DataType, Model, Sequelize, UUID } from "sequelize";
|
|
||||||
import { validatePassword, hashPassword } from "@/util/Auth";
|
|
||||||
|
|
||||||
function getAuth(req: NextApiRequest) {
|
|
||||||
if (req.headers.authorization === undefined) {
|
|
||||||
throw "Basic Auth is required";
|
|
||||||
}
|
|
||||||
const authString = Buffer.from(req.headers.authorization.split(" ")[1], "base64").toString("utf8");
|
|
||||||
return authString.split(":");
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
type UserCredentials = {
|
|
||||||
user: UserModel | undefined,
|
|
||||||
valid: boolean
|
|
||||||
}
|
|
||||||
|
|
||||||
async function verifyUserCredentials(req: NextApiRequest, res: NextApiResponse): Promise<UserCredentials | undefined> {
|
|
||||||
// let user = await MUser.findOne({ where: { username: username } });\
|
|
||||||
|
|
||||||
const auth = getAuth(req) || ["", ""];
|
|
||||||
console.log(auth);
|
|
||||||
let credentials: UserCredentials = { user: undefined, valid: false }
|
|
||||||
const username = auth[0];
|
|
||||||
const password = auth[1];
|
|
||||||
// console.log(req.body);
|
|
||||||
await MUser.sync();
|
|
||||||
await MAuth.sync();
|
|
||||||
|
|
||||||
let user = await MUser.findOne({ where: { username: username } });
|
|
||||||
if (user == undefined) {
|
|
||||||
res.status(401).json("User does not exist");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(await validatePassword(password, user.password))) {
|
|
||||||
res.status(401).json("Invalid password");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
credentials.valid = true;
|
|
||||||
credentials.user = user;
|
|
||||||
return credentials;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
async function GET(req: NextApiRequest, res: NextApiResponse) {
|
|
||||||
let a = req.cookies;
|
|
||||||
console.log(a);
|
|
||||||
let credentials = { userid: req.query.userid, token: req.query.token };
|
|
||||||
if(!credentials.token) return;
|
|
||||||
let authtoken = await MAuth.findOne({
|
|
||||||
where: {
|
|
||||||
token: credentials.token,
|
|
||||||
user_id: credentials.userid
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if(authtoken){
|
|
||||||
// res.setHeader("cookie")
|
|
||||||
setCookie(res, 'auth', authtoken, { path: '/', maxAge: 2592000 });
|
|
||||||
res.status(200).end();
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
res.status(401).end();
|
|
||||||
}
|
|
||||||
// console.log(a);
|
|
||||||
// res.status(200).json(authtokens);
|
|
||||||
}
|
|
||||||
async function POST(req: NextApiRequest, res: NextApiResponse) {
|
|
||||||
try{
|
|
||||||
let cookie = req.cookies;
|
|
||||||
const credentials = await verifyUserCredentials(req, res);
|
|
||||||
if (!credentials || !credentials.valid || !credentials.user)
|
|
||||||
return;
|
|
||||||
const user = await MUser.findOne({ where: { username: credentials.user.username } });
|
|
||||||
if (!user || !user.id)
|
|
||||||
return;
|
|
||||||
const auth = await MAuth.create({ user_id: user.id });
|
|
||||||
if(!auth){
|
|
||||||
res.status(401).end();
|
|
||||||
// res.setHeader("cookie")
|
|
||||||
}
|
|
||||||
setCookie(res, 'authtoken', auth.token, { path: '/', maxAge: 2592000 });
|
|
||||||
setCookie(res, 'user_id', auth.user_id, { path: '/', maxAge: 2592000 });
|
|
||||||
res.status(200).send(auth);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
catch(error){
|
|
||||||
res.status(401).json(error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
||||||
switch (req.method){
|
|
||||||
case 'GET':
|
|
||||||
GET(req, res); break;
|
|
||||||
case 'POST':
|
|
||||||
POST(req, res);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
res.status(404).end(); break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
import mysql2, { Connection, RowDataPacket, OkPacket, QueryError } from "mysql2";
|
|
||||||
import { getConnection } from "@/db";
|
|
||||||
import { Post, postPlaceholder } from "@/model/Models";
|
|
||||||
import { getPosts, IPost } from "@/controller/Post";
|
|
||||||
import { NextApiRequest, NextApiResponse } from "next";
|
|
||||||
import { MPost } from "@/model/Models"
|
|
||||||
import { Sequelize } from "sequelize";
|
|
||||||
|
|
||||||
export default async function handler(req:NextApiRequest, res:NextApiResponse) {
|
|
||||||
await MPost.sync();
|
|
||||||
switch (req.method) {
|
|
||||||
case 'GET':
|
|
||||||
const posts = await MPost.findAll();
|
|
||||||
res.status(200).json(posts);
|
|
||||||
break;
|
|
||||||
case 'POST':
|
|
||||||
try {
|
|
||||||
const post = await MPost.create({
|
|
||||||
title: req.body.title,
|
|
||||||
content: req.body.content,
|
|
||||||
createdAt: new Date(),
|
|
||||||
updatedAt: new Date(),
|
|
||||||
},{ fields: ['title','content'] });
|
|
||||||
const posts2 = await MPost.findAll();
|
|
||||||
res.status(200).json(posts2);
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error)
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
import { NextApiRequest, NextApiResponse } from "next";
|
|
||||||
import { MPost } from "@/model/Models"
|
|
||||||
import { JSON, Sequelize } from "sequelize";
|
|
||||||
|
|
||||||
export default async function handler(req:NextApiRequest, res:NextApiResponse) {
|
|
||||||
const sequelize = new Sequelize({
|
|
||||||
dialect: 'sqlite',
|
|
||||||
storage: 'db.sqlite'
|
|
||||||
});
|
|
||||||
await MPost.sync();
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
import { getPost, IPost } from "@/controller/Post";
|
|
||||||
|
|
||||||
export default async function handler(req:any, res:any) {
|
|
||||||
|
|
||||||
const { slug } = req.query;
|
|
||||||
let rows:IPost[] = await getPost(slug);
|
|
||||||
|
|
||||||
for(let row of rows){
|
|
||||||
row.post = JSON.parse(row.post).post;
|
|
||||||
console.log(row);
|
|
||||||
}
|
|
||||||
res.status(200).json(rows);
|
|
||||||
}
|
|
||||||
@ -1,23 +0,0 @@
|
|||||||
import mysql2, { Connection, RowDataPacket, OkPacket, QueryError } from "mysql2";
|
|
||||||
import { getConnection } from "@/db";
|
|
||||||
import { Post, postPlaceholder } from "@/model/Models";
|
|
||||||
import { getPosts, IPost } from "@/controller/Post";
|
|
||||||
import { NextApiRequest, NextApiResponse } from "next";
|
|
||||||
|
|
||||||
export default async function handler(req:NextApiRequest, res:NextApiResponse) {
|
|
||||||
switch (req.method) {
|
|
||||||
case 'GET':
|
|
||||||
let rows:IPost[] = await getPosts();
|
|
||||||
let posts = [];
|
|
||||||
for(let row of rows){
|
|
||||||
row.post = JSON.parse(row.post).post;
|
|
||||||
console.log(row);
|
|
||||||
}
|
|
||||||
res.status(200).json(rows);
|
|
||||||
break;
|
|
||||||
case 'CREATE':
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,55 +0,0 @@
|
|||||||
// import { getConnection } from "@/db";
|
|
||||||
import { Post, postPlaceholder } from "@/model/Models";
|
|
||||||
import { getPosts, IPost } from "@/controller/Post";
|
|
||||||
import { NextApiRequest, NextApiResponse } from "next";
|
|
||||||
// import { MPost, MUser, MAuth } from "@/model/Models"
|
|
||||||
// import { MPost } from "@/model/sequelize/Post";
|
|
||||||
// import { MAuth } from "@/model/sequelize/Auth";
|
|
||||||
import { MUser } from "@/model/sequelize/User";
|
|
||||||
|
|
||||||
|
|
||||||
import { DataType, Model, Sequelize, UUID } from "sequelize";
|
|
||||||
import { validatePassword, hashPassword } from "@/util/Auth";
|
|
||||||
|
|
||||||
|
|
||||||
async function POST(req: NextApiRequest, res: NextApiResponse){
|
|
||||||
MUser.sync();
|
|
||||||
const username = req.body.username;
|
|
||||||
const password = req.body.password;
|
|
||||||
await MUser.sync()
|
|
||||||
var user = await MUser.findOne({ where: { username: username } });
|
|
||||||
if (user != undefined){
|
|
||||||
res.status(500).json("User with that username already exists");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const hash = await hashPassword(password)
|
|
||||||
user = await MUser.create({
|
|
||||||
username: username,
|
|
||||||
password: hash
|
|
||||||
})
|
|
||||||
res.status(200).json(user);
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
async function GET(req: NextApiRequest, res: NextApiResponse){
|
|
||||||
MUser.sync();
|
|
||||||
const username = req.body.username;
|
|
||||||
const password = req.body.password;
|
|
||||||
await MUser.sync()
|
|
||||||
var users = await MUser.findAll();
|
|
||||||
res.status(200).json(users);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|
||||||
if (req.method === 'POST') {
|
|
||||||
POST(req,res);
|
|
||||||
}
|
|
||||||
else if(req.method === 'GET'){
|
|
||||||
GET(req,res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user