diff --git a/insomnia.json b/insomnia.json
deleted file mode 100644
index 83599b9..0000000
--- a/insomnia.json
+++ /dev/null
@@ -1 +0,0 @@
-{"_type":"export","__export_format":4,"__export_date":"2023-06-12T09:30:08.182Z","__export_source":"insomnia.desktop.app:v2023.2.2","resources":[{"_id":"req_e1f51a43553b49f1ab0dd8144f8838ab","parentId":"fld_b93603394ce3455cb1a0c169de187d03","modified":1686540762016,"created":1686464136593,"url":"{{ _.scheme }}://{{ _.host }}:{{ _.port }}/{{ _.base_path }}/{{ _.route }}","name":"New Request","description":"","method":"GET","body":{},"parameters":[{"id":"pair_7898d6e719ac4a1b91f0f052181a53a7","name":"username","value":"andreas3","description":""},{"id":"pair_b42362652f6c45e4b2023477a4a0fa28","name":"password","value":"changeme","description":""}],"headers":[{"id":"pair_fda94cda80a84d18af14dd872a7b16b8","name":"","value":"","description":""}],"authentication":{"type":"basic","useISO88591":false,"disabled":false,"username":"andreas2","password":"changeme"},"metaSortKey":-1686464136593,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"fld_b93603394ce3455cb1a0c169de187d03","parentId":"wrk_a189b5072b8c4203924446cbf96ec47d","modified":1686464158382,"created":1686464133576,"name":"auth","description":"","environment":{"route":"auth"},"environmentPropertyOrder":{"&":["route"]},"metaSortKey":-1686464133576,"_type":"request_group"},{"_id":"wrk_a189b5072b8c4203924446cbf96ec47d","parentId":null,"modified":1686453338349,"created":1686453338349,"name":"Portfolio","description":"","scope":"design","_type":"workspace"},{"_id":"req_2f70b86802a549cbbf24dff4fb318c73","parentId":"fld_a3c04530d80a4ec091b42f431e450237","modified":1686536923156,"created":1686535644896,"url":"{{ _.scheme }}://{{ _.host }}:{{ _.port }}/{{ _.base_path }}/{{ _.route }}","name":"New Request","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"username\": \"andreas3\",\n\t\"password\": \"changeme\"\n}"},"parameters":[],"headers":[{"id":"pair_fda94cda80a84d18af14dd872a7b16b8","name":"","value":"","description":""},{"name":"Content-Type","value":"application/json"}],"authentication":{},"metaSortKey":-1686464136593,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"fld_a3c04530d80a4ec091b42f431e450237","parentId":"wrk_a189b5072b8c4203924446cbf96ec47d","modified":1686535655573,"created":1686535644894,"name":"User","description":"","environment":{"route":"user"},"environmentPropertyOrder":{"&":["route"]},"metaSortKey":-1686383815714.5,"_type":"request_group"},{"_id":"req_4135b76ecd6e4b38ae875015a1f38c1a","parentId":"fld_b079892e41ea4b9dbf7d00e85df36b4e","modified":1686304187685,"created":1686303504644,"url":"{{ _.scheme }}://{{ _.host }}:{{ _.port }}/{{ _.base_path }}/{{ _.route }}","name":"Get All Posts","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1686303497803,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"fld_b079892e41ea4b9dbf7d00e85df36b4e","parentId":"wrk_a189b5072b8c4203924446cbf96ec47d","modified":1686304180712,"created":1686303497852,"name":"Post","description":"","environment":{"route":"post"},"environmentPropertyOrder":{"&":["route"]},"metaSortKey":-1686303497853,"_type":"request_group"},{"_id":"req_b70167944901490b94817df299f21de6","parentId":"fld_b079892e41ea4b9dbf7d00e85df36b4e","modified":1686453700500,"created":1686453675016,"url":"{{ _.scheme }}://{{ _.host }}:{{ _.port }}/{{ _.base_path }}/{{ _.route }}/1","name":"Get Specific Post","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1686303497753,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_6622010a2bca41beb03b8ba126a6c4b6","parentId":"fld_c82ab5d372fb414e9cf326a69225c7e4","modified":1686458449960,"created":1686455585158,"url":"{{ _.scheme }}://{{ _.host }}:{{ _.port }}/{{ _.base_path }}/{{ _.route }}","name":"Get All Posts","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1686303497803,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"fld_c82ab5d372fb414e9cf326a69225c7e4","parentId":"wrk_a189b5072b8c4203924446cbf96ec47d","modified":1686455601799,"created":1686455585147,"name":"Brown","description":"","environment":{"route":"brown"},"environmentPropertyOrder":{"&":["route"]},"metaSortKey":-1686303497803,"_type":"request_group"},{"_id":"req_eddd37fc4002491892d8acca3dc5d85e","parentId":"fld_c82ab5d372fb414e9cf326a69225c7e4","modified":1686459281655,"created":1686455607594,"url":"{{ _.scheme }}://{{ _.host }}:{{ _.port }}/{{ _.base_path }}/{{ _.route }}","name":"New Request","description":"","method":"POST","body":{"mimeType":"application/json","text":"{\n\t\"title\": \"peepee\",\n\t\"content\": \"poopoo\"\n}"},"parameters":[],"headers":[{"name":"Content-Type","value":"application/json"}],"authentication":{},"metaSortKey":-1686303497778,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"req_1703723ed00c40798a9f8fcd154cffd4","parentId":"fld_c82ab5d372fb414e9cf326a69225c7e4","modified":1686455585160,"created":1686455585160,"url":"{{ _.scheme }}://{{ _.host }}:{{ _.port }}/{{ _.base_path }}/{{ _.route }}/1","name":"Get Specific Post","description":"","method":"GET","body":{},"parameters":[],"headers":[],"authentication":{},"metaSortKey":-1686303497753,"isPrivate":false,"settingStoreCookies":true,"settingSendCookies":true,"settingDisableRenderRequestBody":false,"settingEncodeUrl":true,"settingRebuildPath":true,"settingFollowRedirects":"global","_type":"request"},{"_id":"env_70d3512c1c8840df95de5b7dac78ac9f","parentId":"wrk_a189b5072b8c4203924446cbf96ec47d","modified":1686304013422,"created":1686303473288,"name":"Base Environment","data":{"scheme":"http","host":"localhost","port":3000,"base_path":"api"},"dataPropertyOrder":{"&":["scheme","host","port","base_path"]},"color":null,"isPrivate":false,"metaSortKey":1686303473288,"_type":"environment"},{"_id":"jar_7842a9b1b5aa4d75900c945b6008f4f7","parentId":"wrk_a189b5072b8c4203924446cbf96ec47d","modified":1686303473290,"created":1686303473290,"name":"Default Jar","cookies":[],"_type":"cookie_jar"},{"_id":"spc_a025b787e6754e45a91e8ab3ec1feb42","parentId":"wrk_a189b5072b8c4203924446cbf96ec47d","modified":1686453625860,"created":1686453378493,"fileName":"Portfolio","contents":"openapi: 3.0.0\ninfo:\n description: \"Ask your mom. \\r\\n\\r\\n\n Portfolio [https://aschaafsma.nl](aschaafsma.nl) or on [irc.freenode.net,\n #swagger](https://aschaafsma.nl/irc/). For this sample, you can use the api key\n `special-key` to test the authorization filters.\"\n version: 1.0.2\n title: Portfolio\n termsOfService: http://aschaafsa.nl\n contact:\n email: apiteam@aschaafsma.nl\n license:\n name: GPL 3.0\n url: https://lickmy.nuts\ntags:\n - name: post\n description: A post on the blog\n externalDocs:\n description: Find out more\n url: http://askyour.mom\n - name: tag\n description: Access to Petstore orders\n - name: user\n description: Operations about user\n externalDocs:\n description: Find out more about our store\n url: http://your.mom\npaths:\n /pet:\n post:\n tags:\n - pet\n summary: Add a new pet to the store\n description: \"\"\n operationId: addPet\n requestBody:\n $ref: \"#/components/requestBodies/Pet\"\n responses:\n \"405\":\n description: \"Invalid input\"\n put:\n tags:\n - pet\n summary: Update an existing pet\n description: \"\"\n operationId: updatePet\n requestBody:\n $ref: \"#/components/requestBodies/Pet\"\n responses:\n \"400\":\n description: Invalid ID supplied\n \"404\":\n description: Pet not found\n \"405\":\n description: Validation exception\n /pet/findByStatus:\n get:\n tags:\n - pet\n summary: Finds Pets by status\n description: Multiple status values can be provided with comma separated strings\n operationId: findPetsByStatus\n parameters:\n - name: status\n in: query\n description: Status values that need to be considered for filter\n required: true\n explode: true\n schema:\n type: array\n items:\n type: string\n enum:\n - available\n - pending\n - sold\n default: available\n responses:\n \"200\":\n description: successful operation\n content:\n application/xml:\n schema:\n type: array\n items:\n $ref: \"#/components/schemas/Pet\"\n application/json:\n schema:\n type: array\n items:\n $ref: \"#/components/schemas/Pet\"\n \"400\":\n description: Invalid status value\n /pet/findByTags:\n get:\n tags:\n - pet\n summary: Finds Pets by tags\n description: Multiple tags can be provided with comma separated strings. Use tag1,\n tag2, tag3 for testing.\n operationId: findPetsByTags\n parameters:\n - name: tags\n in: query\n description: Tags to filter by\n required: true\n explode: true\n schema:\n type: array\n items:\n type: string\n responses:\n \"200\":\n description: successful operation\n content:\n application/xml:\n schema:\n type: array\n items:\n $ref: \"#/components/schemas/Pet\"\n application/json:\n schema:\n type: array\n items:\n $ref: \"#/components/schemas/Pet\"\n \"400\":\n description: Invalid tag value\n deprecated: true\n \"/pet/{petId}\":\n get:\n tags:\n - pet\n summary: Find pet by ID\n description: Returns a single pet\n operationId: getPetById\n parameters:\n - name: petId\n in: path\n description: ID of pet to return\n required: true\n schema:\n type: integer\n format: int64\n responses:\n \"200\":\n description: successful operation\n content:\n application/xml:\n schema:\n $ref: \"#/components/schemas/Pet\"\n application/json:\n schema:\n $ref: \"#/components/schemas/Pet\"\n \"400\":\n description: Invalid ID supplied\n \"404\":\n description: Pet not found\n post:\n tags:\n - pet\n summary: Updates a pet in the store with form data\n description: \"\"\n operationId: updatePetWithForm\n parameters:\n - name: petId\n in: path\n description: ID of pet that needs to be updated\n required: true\n schema:\n type: integer\n format: int64\n requestBody:\n content:\n application/x-www-form-urlencoded:\n schema:\n type: object\n properties:\n name:\n description: Updated name of the pet\n type: string\n status:\n description: Updated status of the pet\n type: string\n responses:\n \"405\":\n description: Invalid input\n delete:\n tags:\n - pet\n summary: Deletes a pet\n description: \"\"\n operationId: deletePet\n parameters:\n - name: api_key\n in: header\n required: false\n schema:\n type: string\n - name: petId\n in: path\n description: Pet id to delete\n required: true\n schema:\n type: integer\n format: int64\n responses:\n \"400\":\n description: Invalid ID supplied\n \"404\":\n description: Pet not found\n /store/inventory:\n get:\n tags:\n - store\n summary: Returns pet inventories by status\n description: Returns a map of status codes to quantities\n operationId: getInventory\n responses:\n \"200\":\n description: successful operation\n content:\n application/json:\n schema:\n type: object\n additionalProperties:\n type: integer\n format: int32\n /store/order:\n post:\n tags:\n - store\n summary: Place an order for a pet\n description: \"\"\n operationId: placeOrder\n requestBody:\n content:\n application/json:\n schema:\n $ref: \"#/components/schemas/Order\"\n description: order placed for purchasing the pet\n required: true\n responses:\n \"200\":\n description: successful operation\n content:\n application/xml:\n schema:\n $ref: \"#/components/schemas/Order\"\n application/json:\n schema:\n $ref: \"#/components/schemas/Order\"\n \"400\":\n description: Invalid Order\n \"/store/order/{orderId}\":\n get:\n tags:\n - store\n summary: Find purchase order by ID\n description: For valid response try integer IDs with value >= 1 and <= 10. Other\n values will generated exceptions\n operationId: getOrderById\n parameters:\n - name: orderId\n in: path\n description: ID of pet that needs to be fetched\n required: true\n schema:\n type: integer\n format: int64\n minimum: 1\n maximum: 10\n responses:\n \"200\":\n description: successful operation\n content:\n application/xml:\n schema:\n $ref: \"#/components/schemas/Order\"\n application/json:\n schema:\n $ref: \"#/components/schemas/Order\"\n \"400\":\n description: Invalid ID supplied\n \"404\":\n description: Order not found\n delete:\n tags:\n - store\n summary: Delete purchase order by ID\n description: For valid response try integer IDs with positive integer value. Negative\n or non-integer values will generate API errors\n operationId: deleteOrder\n parameters:\n - name: orderId\n in: path\n description: ID of the order that needs to be deleted\n required: true\n schema:\n type: integer\n format: int64\n minimum: 1\n responses:\n \"400\":\n description: Invalid ID supplied\n \"404\":\n description: Order not found\n /user:\n post:\n tags:\n - user\n summary: Create user\n description: This can only be done by the logged in user.\n operationId: createUser\n requestBody:\n content:\n application/json:\n schema:\n $ref: \"#/components/schemas/User\"\n description: Created user object\n required: true\n responses:\n default:\n description: successful operation\n /user/createWithArray:\n post:\n tags:\n - user\n summary: Creates list of users with given input array\n description: \"\"\n operationId: createUsersWithArrayInput\n requestBody:\n $ref: \"#/components/requestBodies/UserArray\"\n responses:\n default:\n description: successful operation\n /user/createWithList:\n post:\n tags:\n - user\n summary: Creates list of users with given input array\n description: \"\"\n operationId: createUsersWithListInput\n requestBody:\n $ref: \"#/components/requestBodies/UserArray\"\n responses:\n default:\n description: successful operation\n /user/login:\n get:\n tags:\n - user\n summary: Logs user into the system\n description: \"\"\n operationId: loginUser\n parameters:\n - name: username\n in: query\n description: The user name for login\n required: true\n schema:\n type: string\n - name: password\n in: query\n description: The password for login in clear text\n required: true\n schema:\n type: string\n responses:\n \"200\":\n description: successful operation\n headers:\n X-Rate-Limit:\n description: calls per hour allowed by the user\n schema:\n type: integer\n format: int32\n X-Expires-After:\n description: date in UTC when token expires\n schema:\n type: string\n format: date-time\n content:\n application/xml:\n schema:\n type: string\n application/json:\n schema:\n type: string\n \"400\":\n description: Invalid username/password supplied\n /user/logout:\n get:\n tags:\n - user\n summary: Logs out current logged in user session\n description: \"\"\n operationId: logoutUser\n responses:\n default:\n description: successful operation\n \"/user/{username}\":\n get:\n tags:\n - user\n summary: Get user by user name\n description: \"\"\n operationId: getUserByName\n parameters:\n - name: username\n in: path\n description: \"The name that needs to be fetched. Use user1 for testing. \"\n required: true\n schema:\n type: string\n responses:\n \"200\":\n description: successful operation\n content:\n application/xml:\n schema:\n $ref: \"#/components/schemas/User\"\n application/json:\n schema:\n $ref: \"#/components/schemas/User\"\n \"400\":\n description: Invalid username supplied\n \"404\":\n description: User not found\n put:\n tags:\n - user\n summary: Updated user\n description: This can only be done by the logged in user.\n operationId: updateUser\n parameters:\n - name: username\n in: path\n description: name that need to be updated\n required: true\n schema:\n type: string\n requestBody:\n content:\n application/json:\n schema:\n $ref: \"#/components/schemas/User\"\n description: Updated user object\n required: true\n responses:\n \"400\":\n description: Invalid user supplied\n \"404\":\n description: User not found\n delete:\n tags:\n - user\n summary: Delete user\n description: This can only be done by the logged in user.\n operationId: deleteUser\n parameters:\n - name: username\n in: path\n description: The name that needs to be deleted\n required: true\n schema:\n type: string\n responses:\n \"400\":\n description: Invalid username supplied\n \"404\":\n description: User not found\nexternalDocs:\n description: Find out more about your mom\n url: http://your.mom\nservers:\n - url: https://petstore.swagger.io/v2\ncomponents:\n requestBodies:\n UserArray:\n content:\n application/json:\n schema:\n type: array\n items:\n $ref: \"#/components/schemas/User\"\n description: List of user object\n required: true\n Pet:\n content:\n application/json:\n schema:\n $ref: \"#/components/schemas/Pet\"\n application/xml:\n schema:\n $ref: \"#/components/schemas/Pet\"\n description: Pet object that needs to be added to the store\n required: true\n schemas:\n Order:\n type: object\n properties:\n id:\n type: integer\n format: int64\n petId:\n type: integer\n format: int64\n quantity:\n type: integer\n format: int32\n shipDate:\n type: string\n format: date-time\n status:\n type: string\n description: Order Status\n enum:\n - placed\n - approved\n - delivered\n complete:\n type: boolean\n default: false\n xml:\n name: Order\n User:\n type: object\n properties:\n id:\n type: integer\n format: int64\n username:\n type: string\n firstName:\n type: string\n lastName:\n type: string\n email:\n type: string\n password:\n type: string\n phone:\n type: string\n userStatus:\n type: integer\n format: int32\n description: User Status\n xml:\n name: User\n Category:\n type: object\n properties:\n id:\n type: integer\n format: int64\n name:\n type: string\n xml:\n name: Category\n Tag:\n type: object\n properties:\n id:\n type: integer\n format: int64\n name:\n type: string\n xml:\n name: Tag\n Pet:\n type: object\n required:\n - name\n - photoUrls\n properties:\n id:\n type: integer\n format: int64\n category:\n $ref: \"#/components/schemas/Category\"\n name:\n type: string\n example: doggie\n photoUrls:\n type: array\n xml:\n name: photoUrl\n wrapped: true\n items:\n type: string\n tags:\n type: array\n xml:\n name: tag\n wrapped: true\n items:\n $ref: \"#/components/schemas/Tag\"\n status:\n type: string\n description: pet status in the store\n enum:\n - available\n - pending\n - sold\n xml:\n name: Pet\n ApiResponse:\n type: object\n properties:\n code:\n type: integer\n format: int32\n type:\n type: string\n message:\n type: string","contentType":"yaml","_type":"api_spec"},{"_id":"env_c42d5b08a21141908834b43e42ee6e46","parentId":"env_70d3512c1c8840df95de5b7dac78ac9f","modified":1686541816225,"created":1686303739938,"name":"Dev","data":{"scheme":"http","host":"localhost","port":3000,"base_path":"api"},"dataPropertyOrder":{"&":["scheme","host","port","base_path"]},"color":null,"isPrivate":false,"metaSortKey":1686303739938,"_type":"environment"}]}
\ No newline at end of file
diff --git a/src/app/admin/layout.tsx b/src/app/admin/layout.tsx
index 01fb0c8..928cb35 100644
--- a/src/app/admin/layout.tsx
+++ b/src/app/admin/layout.tsx
@@ -1,25 +1,30 @@
// import '../globals.css'
-import { Inter } from 'next/font/google'
-import StyledJsxRegistry from '../registry';
-import Providers from '@/providers/providers';
-import 'bootstrap/dist/css/bootstrap.css';
-import { Toaster } from 'react-hot-toast';
+import { Inter } from "next/font/google";
+import StyledJsxRegistry from "../registry";
+import ContextProviders from "@/providers/contextproviders";
+import "bootstrap/dist/css/bootstrap.css";
+import { Toaster } from "react-hot-toast";
-const inter = Inter({ subsets: ['latin'], fallback: ['system-ui', 'arial'] })
+const inter = Inter({ subsets: ["latin"], fallback: ["system-ui", "arial"] });
export const metadata = {
- title: 'Create Next App',
- description: 'Generated by create next app',
-}
+ title: "Create Next App",
+ description: "Generated by create next app",
+};
export default function RootLayout({
- children,
+ children,
}: {
- children: React.ReactNode
+ children: React.ReactNode;
}) {
- return (
-
-
{children}
-
- )
+ return (
+
+
+
+
+ {children}
+
+
+
+ );
}
diff --git a/src/app/api-doc/page.tsx b/src/app/api-doc/page.tsx
new file mode 100644
index 0000000..f429059
--- /dev/null
+++ b/src/app/api-doc/page.tsx
@@ -0,0 +1,11 @@
+import { getApiDocs } from "@/lib/swagger";
+import ReactSwagger from "@/components/client/SwaggerComponent";
+
+export default async function IndexPage() {
+ const spec = await getApiDocs();
+ return (
+
+ );
+}
\ No newline at end of file
diff --git a/src/app/api/attachment/route.ts b/src/app/api/attachment/route.ts
index 632655f..462c17a 100644
--- a/src/app/api/attachment/route.ts
+++ b/src/app/api/attachment/route.ts
@@ -1,6 +1,5 @@
"use server";
-import { APIError, attemptAPIAction } from "@/util";
import {
sequelize,
Bucket,
@@ -20,6 +19,7 @@ import {
} from "@/app/lib/actions/entitymanagement/attachment/attachmentActions";
import { Attributes } from "@sequelize/core";
import { RequestCookie } from "next/dist/compiled/@edge-runtime/cookies";
+import { APIError, attemptAPIAction } from "@/util/api";
export async function tryCreateAttachment(request: Request) {
// Make sure the DB is ready
@@ -127,6 +127,17 @@ export async function tryCreateAttachment(request: Request) {
);
}
+
+
+/**
+ * @swagger
+ * /api/attachment:
+ * get:
+ * description: Returns all attachments
+ * responses:
+ * 200:
+ * description: idk
+ */
export async function tryFetchAttachments(request: Request) {
await Post.sync();
diff --git a/src/app/api/auth/route.ts b/src/app/api/auth/route.ts
index 1da075f..fe4d193 100644
--- a/src/app/api/auth/route.ts
+++ b/src/app/api/auth/route.ts
@@ -1,8 +1,8 @@
"use server";
import { cookies } from "next/headers";
-import { APIError, UserAuth, parseBasicAuth, getAssociatedUser } from "@/util";
import { Auth, User } from "@/models";
+import { APIError, getAssociatedUser, parseBasicAuth } from "@/util/api";
async function tryAuth(request: Request) {
// await User.sync();
@@ -63,11 +63,12 @@ async function tryAuth(request: Request) {
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;
- }
- }
+ } catch(e){
+ if (e instanceof APIError){
+ return new Response(e.info.responseText,{status:e.info.status});
+ }
+ else{
+ throw e;
+ }
+ }
}
diff --git a/src/app/api/setupDB/route.ts b/src/app/api/setupDB/route.ts
index 83ac650..4b51a4b 100644
--- a/src/app/api/setupDB/route.ts
+++ b/src/app/api/setupDB/route.ts
@@ -1,159 +1,189 @@
-'use server'
+"use server";
import { cookies } from "next/headers";
-import { APIError} from "@/util/api/error"
-import { UserAuth, parseBasicAuth, getAssociatedUser } from "@/util/api/user"
-import { Attachment, Auth, Bucket, DBState, Post, PostTag, Project, Tag, User, UserPerms,dbSync,sequelize} from "@/models";
+import { APIError } from "@/util/api/error";
+import {
+ Attachment,
+ Auth,
+ Bucket,
+ DBState,
+ Post,
+ PostTag,
+ Project,
+ Tag,
+ User,
+ UserPerms,
+ dbSync,
+ sequelize,
+} from "@/models";
import Sequelize, { CreationAttributes, DataTypes } from "@sequelize/core";
-import { SqliteColumnsDescription, SqliteDialect, SqliteQueryInterface } from "@sequelize/sqlite3";
+import {
+ SqliteColumnsDescription,
+ SqliteDialect,
+ SqliteQueryInterface,
+} from "@sequelize/sqlite3";
import { hashpassword } from "@/util/auth";
import { copyFile, readFileSync } from "fs";
import path from "path";
-import { Attributes } from '@sequelize/core';
-import { DeepPartial } from "@/util/DeepPartial";
import { UUID } from "crypto";
+import { runApiAction } from "@/util/api";
-async function seedUsers(qif: SqliteQueryInterface){
- const fp = path.resolve('./db/seed/users.json');
- const json: {users: CreationAttributes[]} = JSON.parse(Buffer.from(readFileSync(fp).valueOf()).toString());
+async function seedUsers(qif: SqliteQueryInterface) {
+ const fp = path.resolve("./db/seed/users.json");
+ const json: { users: CreationAttributes[] } = JSON.parse(
+ Buffer.from(readFileSync(fp).valueOf()).toString()
+ );
- const users = json.users.map(async user=>{
- user.password = await hashpassword(user.password);
- return user;
- })
-
- const dbUsers = await User.bulkCreate(await Promise.all(users), {include: User.associations.perms})
+ const users = json.users.map(async (user) => {
+ user.password = await hashpassword(user.password);
+ return user;
+ });
+
+ const dbUsers = await User.bulkCreate(await Promise.all(users), {
+ include: User.associations.perms,
+ });
}
-async function seedPosts(qif: SqliteQueryInterface){
- const fp = path.resolve('./db/seed/posts.json');
- const json: {users: CreationAttributes[]} = JSON.parse(Buffer.from(readFileSync(fp).valueOf()).toString());
- const projects =[
- {
- "name": "Blog",
- "readableIdentifier": "blog",
- "posts": [
- {
- "title": "Test Post",
- "content": "# Hello \nthis is some **test** markdown and we make some edits\n",
- "description": "A new post to test the blog system",
- "project_id": 1,
- "user_id": 1,
- "buckets": [
- {
- "id": "788dfc19-55ba-482c-8124-277702296dfb",
- "attachments": [
- {
- "filename": "FB_IMG_1716665756868.jpg"
- }
- ]
- }
- ]
- }
- ]
- }]
- projects.map(project=>{
- Project.create({name: project.name, readableIdentifier: project.readableIdentifier});
- project.posts.map(async post=>{
- const pst = await Post.create({title:post.title, content:post.content, description:post.description, project_id: post.project_id, user_id: post.user_id});
- post.buckets.map(async bucket=>{
- pst.createBucket({id:bucket.id as UUID});
- bucket.attachments.map(attachment=>{
- Attachment.create({bucket_id:bucket.id as UUID, filename: attachment.filename}).then((a)=>{
- copyFile(
- path.resolve('.','db','seed','post',a.filename),
- path.resolve('.','bucket',bucket.id,a.filename),
- ()=>{
+async function seedPosts(qif: SqliteQueryInterface) {
+ const fp = path.resolve("./db/seed/posts.json");
+ const json: { users: CreationAttributes[] } = JSON.parse(
+ Buffer.from(readFileSync(fp).valueOf()).toString()
+ );
+ const projects = [
+ {
+ name: "Blog",
+ readableIdentifier: "blog",
+ posts: [
+ {
+ title: "Test Post",
+ content:
+ "# Hello \nthis is some **test** markdown and we make some edits\n",
+ description: "A new post to test the blog system",
+ project_id: 1,
+ user_id: 1,
+ buckets: [
+ {
+ id: "788dfc19-55ba-482c-8124-277702296dfb",
+ attachments: [
+ {
+ filename: "FB_IMG_1716665756868.jpg",
+ },
+ ],
+ },
+ ],
+ },
+ ],
+ },
+ ];
+ projects.map((project) => {
+ Project.create({
+ name: project.name,
+ readableIdentifier: project.readableIdentifier,
+ });
+ project.posts.map(async (post) => {
+ const pst = await Post.create({
+ title: post.title,
+ content: post.content,
+ description: post.description,
+ project_id: post.project_id,
+ user_id: post.user_id,
+ });
+ post.buckets.map(async (bucket) => {
+ pst.createBucket({ id: bucket.id as UUID });
+ bucket.attachments.map((attachment) => {
+ Attachment.create({
+ bucket_id: bucket.id as UUID,
+ filename: attachment.filename,
+ }).then((a) => {
+ copyFile(
+ path.resolve(".", "db", "seed", "post", a.filename),
+ path.resolve(".", "bucket", bucket.id, a.filename),
+ () => {}
+ );
+ });
+ });
+ });
+ });
+ });
- }
- )
- })
- })
- })
- })
- })
-
-
-
-
- const project = await Project.findOne({where: {
- readableIdentifier: 'blog'
- }}).then(e=> e ? e : Project.create({name:'General Blog',readableIdentifier:'blog'}));
+ const project = await Project.findOne({
+ where: {
+ readableIdentifier: "blog",
+ },
+ }).then((e) =>
+ e
+ ? e
+ : Project.create({
+ name: "General Blog",
+ readableIdentifier: "blog",
+ })
+ );
}
+async function seedDatabase(qif: SqliteQueryInterface) {
+ await seedUsers(qif);
+ await seedPosts(qif);
-
-
-
-async function seedDatabase(qif:SqliteQueryInterface){
- await seedUsers(qif);
- await seedPosts(qif)
-
- // await Post.create({
- // title: 'Test Post',
- // content: `
- // # Hello
- // this is some **test** markdown
- // `,
- // project_id: project.id,
- // user_id: user.id
- // })
- // await Post.create({
- // title: 'Test Post 2',
- // content: `
- // # Hello
- // this is amother post with some **test** markdown
- // `,
- // project_id: project.id,
- // user_id: user.id
- // })
+ // await Post.create({
+ // title: 'Test Post',
+ // content: `
+ // # Hello
+ // this is some **test** markdown
+ // `,
+ // project_id: project.id,
+ // user_id: user.id
+ // })
+ // await Post.create({
+ // title: 'Test Post 2',
+ // content: `
+ // # Hello
+ // this is amother post with some **test** markdown
+ // `,
+ // project_id: project.id,
+ // user_id: user.id
+ // })
}
-async function trySetup(request:Request){
- await dbSync;
+export async function GET(request: Request) {
+ runApiAction(async (request) => {
+ await dbSync;
- const queryInterface = sequelize.queryInterface
-
+ const queryInterface = sequelize.queryInterface;
- const version = (await DBState.findAll()).sort((a,b)=> ((a.version > b.version) ? 1 : -1)).map(a=>a.version)[0];
+ const version = (await DBState.findAll())
+ .sort((a, b) => (a.version > b.version ? 1 : -1))
+ .map((a) => a.version)[0];
-
+ switch (version) {
+ case 1:
+ break;
+ default:
+ seedDatabase(queryInterface);
+ const postsRows: SqliteColumnsDescription = await queryInterface
+ .describeTable(Post.table.tableName)
+ .then((t) => t);
+ if (!postsRows["project_id"])
+ queryInterface.addColumn("Posts", "project_id", {
+ type: DataTypes.INTEGER,
+ acceptsNull: () => false,
+ defaultValue: 1,
+ });
+ break;
+ }
- switch(version){
- case 1:
- break;
- default:
- seedDatabase(queryInterface);
- const postsRows:SqliteColumnsDescription = await queryInterface.describeTable(Post.table.tableName).then(t=>t);
- if (!postsRows['project_id']) queryInterface.addColumn('Posts','project_id',{type: DataTypes.INTEGER, acceptsNull:()=>false,defaultValue:1})
- break;
- }
-
- return new Response(
- JSON.stringify(
- {
- test: await queryInterface.describeTable('Posts').then(t=>t)
- }),
- {
- status: 200,
- headers:{
- "Content-Type": "text/JSON"
- }
- }
- );
-}
-
-export async function GET(request:Request){
- try{
- return await trySetup(request);
- }
- catch(e){
- if (e instanceof APIError){
- return new Response(e.info.responseText,{status:e.info.status});
- }
- else{
- throw e;
- }
- }
+ return new Response(
+ JSON.stringify({
+ test: await queryInterface
+ .describeTable("Posts")
+ .then((t) => t),
+ }),
+ {
+ status: 200,
+ headers: {
+ "Content-Type": "text/JSON",
+ },
+ }
+ );
+ }, request);
}
diff --git a/src/app/api/user/route.ts b/src/app/api/user/route.ts
index 1d4f72c..b86e266 100644
--- a/src/app/api/user/route.ts
+++ b/src/app/api/user/route.ts
@@ -90,7 +90,7 @@ async function attemptGetUsers(request:Request){
);
}
-export async function GET(request:Request){
+export async function GET(request:Request): Promise{
try{
return await attemptGetUsers(request);
}
diff --git a/src/app/article/[...slug]/page.tsx b/src/app/article/[...slug]/page.tsx
index 860a7d9..00c9113 100644
--- a/src/app/article/[...slug]/page.tsx
+++ b/src/app/article/[...slug]/page.tsx
@@ -12,7 +12,7 @@ import "@/app/index.css"
import { Post } from "@/models";
import { Attributes } from "@sequelize/core";
-import { DeepPartial } from "@/util/DeepPartial";
+import { DeepPartial } from "@/util/deeppartial";
async function getData(slug:string):Promise> {
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index 98a4a16..8cda69c 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -1,7 +1,7 @@
import './globals.css'
import { Inter } from 'next/font/google'
import StyledJsxRegistry from './registry';
-import Providers from '@/providers/providers';
+import ContextProviders from '@/providers/contextproviders';
const inter = Inter({ subsets: ['latin'], fallback: ['system-ui', 'arial'] })
@@ -17,7 +17,7 @@ export default function RootLayout({
}) {
return (
- {children}
+ {children}
)
}
diff --git a/src/app/lib/actions/actions.ts b/src/app/lib/actions/actions.ts
index 649b66e..2cdd8d9 100644
--- a/src/app/lib/actions/actions.ts
+++ b/src/app/lib/actions/actions.ts
@@ -1,129 +1,154 @@
-'use server'
-
+"use server";
+
import { constructAPIUrl } from "@/util/url";
-import { cookies } from "next/headers"
-import { parseSetCookie } from "@/util/parseSetCookie";
-import makeFetchCookie from 'fetch-cookie';
-import fetchCookie from "fetch-cookie";
-import { Attribute, Attributes } from "@sequelize/core";
-import { User, Auth } from "@/models";
-import { AuthProps } from "@/providers/providers";
-import { ActionResult } from "./ActionResult";
+import { cookies } from "next/headers";
+import { parseSetCookie } from "@/util/cookies";
+import makeFetchCookie from "fetch-cookie";
+import fetchCookie from "fetch-cookie";
+import { User, Auth } from "@/models";
+import { AuthContextProviderProps } from "@/providers";
type LoginReturn = {
- cookie?:unknown,
- errorMessage?:string;
+ cookie?: unknown;
+ errorMessage?: string;
+};
+
+async function attemptAPILogin(
+ method: string,
+ formData: FormData
+): Promise {
+ // Check if form data is present with required fields, return null if not
+ if (
+ !formData ||
+ !formData.get("input_username") ||
+ !formData.get("input_password")
+ )
+ return null;
+
+ // Instantiate header object
+ let headers: Headers = new Headers();
+
+ // Prepare fetchCookie
+ const { CookieJar, Cookie } = fetchCookie.toughCookie;
+ const jar = new CookieJar();
+ const fetchWithCookie = makeFetchCookie(fetch, jar);
+
+ // Set Basic Auth
+ headers.set(
+ "Authorization",
+ `Basic ${Buffer.from(
+ `${formData.get("input_username")}:${formData.get(
+ "input_password"
+ )}`
+ ).toString("base64")}`
+ );
+ let res = await fetchWithCookie(await constructAPIUrl("auth"), {
+ method: "POST",
+ credentials: "include",
+ headers: headers,
+ });
+
+ console.log(jar.store.idx["localhost"]["/"]);
+
+ let koek = res.headers.getSetCookie();
+
+ let cookieDict = parseSetCookie(koek);
+
+ await cookies().set("auth", cookieDict.auth);
+ return {
+ cookie: cookieDict.auth,
+ errorMessage: "",
+ };
+ // console.log(koek);
}
-async function attemptAPILogin(method:string,formData:FormData):Promise
-{
- // Check if form data is present with required fields, return null if not
- if(!formData || !formData.get('input_username') || !formData.get('input_password')) return null;
-
- // Instantiate header object
- let headers:Headers = new Headers();
-
- // Prepare fetchCookie
- const { CookieJar, Cookie } = fetchCookie.toughCookie;
- const jar = new CookieJar()
- const fetchWithCookie = makeFetchCookie(fetch, jar);
-
- // Set Basic Auth
- headers.set('Authorization', `Basic ${Buffer.from(`${formData.get('input_username')}:${formData.get('input_password')}`).toString('base64')}`);
- let res = await fetchWithCookie(constructAPIUrl("auth"), {
- method:'POST',
- credentials: 'include',
- headers:headers,
- });
-
- console.log(jar.store.idx['localhost']['/']);
-
- let koek = res.headers.getSetCookie();
-
- let cookieDict = parseSetCookie(koek);
-
- await cookies().set('auth', cookieDict.auth);
- return {
- cookie:cookieDict.auth,
- errorMessage:""
- };
- // console.log(koek);
+export async function serverAttemptAuthenticateUser(
+ _currentState: unknown,
+ formData: FormData
+): Promise {
+ try {
+ const signInStatus = await attemptAPILogin("credentials", formData);
+ return signInStatus;
+ } catch (error: any) {
+ if (error) {
+ console.log(error);
+ switch (error.type) {
+ case "CredentialsSignin":
+ return { errorMessage: "invalidCredentials" };
+ default:
+ return { errorMessage: "Something went wrong." };
+ }
+ }
+ throw Error;
+ }
}
-export async function serverAttemptAuthenticateUser(_currentState: unknown, formData: FormData):Promise
-{
- try {
- const signInStatus = await attemptAPILogin('credentials', formData)
- return signInStatus;
- } catch (error:any) {
- if (error) {
- switch (error.type) {
- case 'CredentialsSignin': return { errorMessage: 'invalidCredentials' };
- default: return { errorMessage: 'Something went wrong.' };
- }
- }
- throw Error
- }
+export async function serverValidateSessionCookie(
+ koek: string
+): Promise {
+ const validateSession = await fetch(
+ await constructAPIUrl("auth/validate"),
+ {
+ method: "POST",
+ headers: {
+ Cookie: `auth=${koek};`,
+ },
+ }
+ );
+ if (validateSession.status == 200) return true;
+ else return false;
}
-export async function serverValidateSessionCookie(koek:string):Promise
-{
- const validateSession = await fetch(constructAPIUrl("auth/validate"),{
- method:"POST",
- headers:{
- Cookie: `auth=${koek};`
- }
- });
- if(validateSession.status == 200)
- return true
- else
- return false
+export async function userIsAdmin(): Promise {
+ const cookieAuthValue = await cookies().get("auth")?.value;
+ const cookieAuthSanitized = cookieAuthValue
+ ? JSON.parse(JSON.stringify(cookieAuthValue))
+ : "";
+
+ if (!cookieAuthSanitized) return false;
+ const parsedAuth = JSON.parse(cookieAuthSanitized);
+
+ if (!parsedAuth.id || !parsedAuth.token || !parsedAuth.user_id)
+ return false;
+
+ const p: AuthContextProviderProps = {
+ auth: {
+ id: parsedAuth.id,
+ token: parsedAuth.token,
+ user_id: parsedAuth.user_id,
+ },
+ };
+
+ const foundAuth = await Auth.findOne({ where: { id: p.auth?.id } });
+ if (!foundAuth || foundAuth.token != p.auth?.token) return false;
+
+ return true;
}
-export async function userIsAdmin():Promise
-{
- const cookieAuthValue = await cookies().get('auth')?.value;
- const cookieAuthSanitized = cookieAuthValue? JSON.parse(JSON.stringify(cookieAuthValue)) : "";
+export async function getCookieAuth(): Promise {
+ const cookieAuthValue = await cookies().get("auth")?.value;
+ const cookieAuthSanitized = cookieAuthValue
+ ? JSON.parse(JSON.stringify(cookieAuthValue))
+ : "";
+ console.log("kanker koek");
- if(!cookieAuthSanitized) return false;
- const parsedAuth = JSON.parse(cookieAuthSanitized);
-
- if(!parsedAuth.id || !parsedAuth.token || !parsedAuth.user_id) return false
-
- const p:AuthProps = {
- auth: {
- id:parsedAuth.id,
- token:parsedAuth.token,
- user_id:parsedAuth.user_id
- }
- };
-
- const foundAuth = await Auth.findOne({where: { id: p.auth?.id}});
- if(!foundAuth || foundAuth.token != p.auth?.token ) return false;
+ if (!cookieAuthSanitized) return {};
- return true;
-}
-
-export async function getCookieAuth():Promise
-{
- const cookieAuthValue = await cookies().get('auth')?.value;
- const cookieAuthSanitized = cookieAuthValue? JSON.parse(JSON.stringify(cookieAuthValue)) : "";
- console.log("kanker koek")
-
- if(!cookieAuthSanitized) return {}
-
- const kd = JSON.parse(cookieAuthSanitized);
- if(!kd.id || !kd.token || !kd.user_id) return {};
-
- const foundAuth = await Auth.findOne({where: { id: kd.id},include:{model:User}});
- if(!foundAuth) return {};
- const authObject:AuthProps = {
- auth: {
- id:kd.id,
- token:kd.token,
- user_id:kd.user_id
- },
- user: await foundAuth.user
- }
- return authObject;
+ const kd = JSON.parse(cookieAuthSanitized);
+ if (!kd.id || !kd.token || !kd.user_id) return {};
+
+ const foundAuth = await Auth.findOne({
+ where: { id: kd.id },
+ include: { model: User },
+ });
+ if (!foundAuth) return {};
+ const authObject: AuthContextProviderProps = {
+ auth: {
+ id: kd.id,
+ token: kd.token,
+ user_id: kd.user_id,
+ },
+ user: await foundAuth.user,
+ };
+ return authObject;
}
diff --git a/src/app/page.tsx b/src/app/page.tsx
index 521bfbf..dc2a1df 100644
--- a/src/app/page.tsx
+++ b/src/app/page.tsx
@@ -7,7 +7,7 @@ import ReactDOM from "react";
import "/public/global.css"
import "./index.css"
import { Post } from "@/models";
-import { constructAPIUrl } from "@/util";
+import { constructAPIUrl } from "@/util/url";
import Link from "next/link";
import { Attributes } from "@sequelize/core";
@@ -17,7 +17,7 @@ type DeepPartial = T extends object ? {
export default async function Test() {
- const response = await fetch(constructAPIUrl('post'));
+ const response = await fetch(await constructAPIUrl('post'));
const articles:Array> = await response.json();
diff --git a/src/components/client/SwaggerComponent.tsx b/src/components/client/SwaggerComponent.tsx
new file mode 100644
index 0000000..7d4bd6a
--- /dev/null
+++ b/src/components/client/SwaggerComponent.tsx
@@ -0,0 +1,14 @@
+'use client';
+
+import SwaggerUI from 'swagger-ui-react';
+import 'swagger-ui-react/swagger-ui.css';
+
+type Props = {
+ spec: Record,
+};
+
+function ReactSwagger({ spec }: Props) {
+ return ;
+}
+
+export default ReactSwagger;
\ No newline at end of file
diff --git a/src/components/client/admin/CAuthHandler.tsx b/src/components/client/admin/CAuthHandler.tsx
new file mode 100644
index 0000000..699b2a2
--- /dev/null
+++ b/src/components/client/admin/CAuthHandler.tsx
@@ -0,0 +1,15 @@
+'use client'
+import { AuthContext, AuthContextProviderProps } from "@/providers";
+import { ReactNode } from "react"
+
+type CAuthProviderProps = {
+ children?:ReactNode;
+ authProps:AuthContextProviderProps
+}
+
+export default function CAuthProvider(props:CAuthProviderProps){
+
+ return (
+ {props.children}
+ )
+}
\ No newline at end of file
diff --git a/src/components/client/admin/loginForm.tsx b/src/components/client/admin/CLoginForm.tsx
similarity index 82%
rename from src/components/client/admin/loginForm.tsx
rename to src/components/client/admin/CLoginForm.tsx
index 919dda7..a0a61be 100644
--- a/src/components/client/admin/loginForm.tsx
+++ b/src/components/client/admin/CLoginForm.tsx
@@ -1,19 +1,10 @@
'use client'
import { serverAttemptAuthenticateUser } from "@/app/lib/actions/actions";
-import { AuthContext } from "@/providers/providers";
-import { constructAPIUrl } from "@/util/url";
-import { createContext, useState } from "react";
import { useFormState, useFormStatus } from "react-dom";
-// async function authenticate(){
-// const url = await constructAPIUrl("auth");
-// const auth = await fetch(url);
-// }
-
-
-export default function LoginForm(){
+export default function CLoginForm(){
const [loginResult, dispatch] = useFormState(serverAttemptAuthenticateUser, undefined);
return (
diff --git a/src/components/client/admin/PostEditor.tsx b/src/components/client/admin/PostEditor.tsx
index 6591e51..36938ee 100644
--- a/src/components/client/admin/PostEditor.tsx
+++ b/src/components/client/admin/PostEditor.tsx
@@ -6,9 +6,6 @@ import { EntityEditorTextArea } from '../input/EntityEditorTextArea';
import {
ChangeEventHandler,
MouseEventHandler,
- MutableRefObject,
- useLayoutEffect,
- useRef,
useState,
} from "react";
import {
diff --git a/src/components/client/admin/PostTable.tsx b/src/components/client/admin/PostTable.tsx
index 05e18e5..009c0f7 100644
--- a/src/components/client/admin/PostTable.tsx
+++ b/src/components/client/admin/PostTable.tsx
@@ -19,7 +19,7 @@ import {
} from "@/app/lib/actions/entityManagement/post/postActions";
import { PostViewProps } from "@/views/admin/post";
-import { aifa, StateHook } from "@/util/";
+import { StateHook } from "@/util/";
export type PostTableStateProps = {
posts: StateHook;
@@ -110,13 +110,10 @@ export default function PostTable({
: `${post.content.substring(0, 255)}...`}
- {aifa(
- projects.find((e) => {
- console.log(e.id);
- return e.id == post.project.id;
- })?.readableIdentifier,
- "uncategorized"
- )}
+ {projects.find((e) => {
+ console.log(e.id);
+ return e.id == post.project.id;
+ })?.readableIdentifier || "uncategorized"}
|
{post.createdAt?.toString()} |
{post.updatedAt?.toString()} |
diff --git a/src/components/client/admin/clientAuthHandler.tsx b/src/components/client/admin/clientAuthHandler.tsx
deleted file mode 100644
index 1dff506..0000000
--- a/src/components/client/admin/clientAuthHandler.tsx
+++ /dev/null
@@ -1,16 +0,0 @@
-'use client'
-import { AuthContext, AuthProps } from "@/providers/providers";
-import { ReactNode, createContext } from "react"
-
-type Props = {
- children?:ReactNode;
- authProps:AuthProps
-}
-
-
-export default function ClientAuthHandler(props:Props){
-
- return (
- {props.children}
- )
-}
\ No newline at end of file
diff --git a/src/components/client/input/EntityEditorTextArea.tsx b/src/components/client/input/EntityEditorTextArea.tsx
index b4b2941..c3b3783 100644
--- a/src/components/client/input/EntityEditorTextArea.tsx
+++ b/src/components/client/input/EntityEditorTextArea.tsx
@@ -5,7 +5,6 @@ import {
MutableRefObject,
useLayoutEffect,
ChangeEventHandler,
- useState,
} from "react";
import { StateHook } from "@/util";
diff --git a/src/components/server/admin/authHandler.tsx b/src/components/server/admin/authHandler.tsx
index fc34cde..d1e3c14 100644
--- a/src/components/server/admin/authHandler.tsx
+++ b/src/components/server/admin/authHandler.tsx
@@ -1,43 +1,46 @@
-'use server'
+"use server";
import { cookies } from "next/headers";
-import LoginForm from "@/components/client/admin/loginForm";
-import ClientAuthHandler from "@/components/client/admin/clientAuthHandler";
+import CLoginForm from "@/components/client/admin/CLoginForm";
+import ClientAuthHandler from "@/components/client/admin/CAuthHandler";
import { serverValidateSessionCookie } from "@/app/lib/actions/actions";
import { ReactNode } from "react";
-import { AuthContext, AuthProps } from "@/providers/providers";
-
+import { AuthContextProviderProps } from "@/providers";
interface Props {
- children?: ReactNode;
- params?: any;
- requiredRole?: number;
+ children?: ReactNode;
+ params?: any;
+ requiredRole?: number;
} // We interfacing lads
-
export default async function AuthHandler(props: Props) {
- const protoKoek = await cookies().get('auth')?.value;
- const koek = decodeURIComponent(protoKoek ? protoKoek: "");
- // console.log("koekje:" + koek)
- let p:AuthProps = {
- };
- if(koek){
- const kd = JSON.parse(koek);
- if(kd.id && kd.token && kd.user_id){
- p = {
- auth: {
- id:kd.id,
- token:kd.token,
- user_id:kd.user_id
- }
- }
- }
- }
+ const protoKoek = await cookies().get("auth")?.value;
+ const koek = decodeURIComponent(protoKoek ? protoKoek : "");
+ // console.log("koekje:" + koek)
+ let p: AuthContextProviderProps = {};
+ if (koek) {
+ const kd = JSON.parse(koek);
+ if (kd.id && kd.token && kd.user_id) {
+ p = {
+ auth: {
+ id: kd.id,
+ token: kd.token,
+ user_id: kd.user_id,
+ },
+ };
+ }
+ }
- return (
-
- {!(koek && await serverValidateSessionCookie(koek)) ? { } : {props.children}}
-
- );
+ return (
+
+ {!(koek && (await serverValidateSessionCookie(koek))) ? (
+ {}
+ ) : (
+
+ {props.children}
+
+ )}
+
+ );
}
diff --git a/src/components/shared/bootstrap.tsx b/src/components/shared/bootstrap.tsx
deleted file mode 100644
index 4f53cf9..0000000
--- a/src/components/shared/bootstrap.tsx
+++ /dev/null
@@ -1,10 +0,0 @@
-'use client'
-import 'bootstrap/dist/css/bootstrap.css';
-import { useEffect } from 'react';
-
-export default function Bootstrap(Component, children, pageProps){
- useEffect(() => {
- typeof document !== undefined ? require('bootstrap/dist/js/bootstrap') : null
- }, []);
- return <>>;
-}
\ No newline at end of file
diff --git a/src/components/shared/news/article-preview.tsx b/src/components/shared/news/article-preview.tsx
index 5e59082..a99e97a 100644
--- a/src/components/shared/news/article-preview.tsx
+++ b/src/components/shared/news/article-preview.tsx
@@ -8,7 +8,7 @@ import Link from "next/link";
import { redirect } from 'next/navigation';
import { Router } from "next/router";
import { useRouter } from 'next/navigation'
-import { truncateString } from "@/util/utils";
+import { truncateString } from "@/util/strings";
// @ts-ignore
import { MDXRemote } from "next-mdx-remote/rsc";
import { ExampleComponent } from "./article";
diff --git a/src/components/shared/news/tagbar.module.css b/src/components/shared/news/tagbar.module.css
index d50dac2..991e0b3 100644
--- a/src/components/shared/news/tagbar.module.css
+++ b/src/components/shared/news/tagbar.module.css
@@ -7,7 +7,7 @@
margin-left:0px;
padding: 1px 5px 1px 5px;
border-radius: 20%;
- *display: inline;
+ display: inline;
}
.tagbar{
margin: 0px 0px 0px 0px;
diff --git a/src/components/views/admin/post/CPostView.tsx b/src/components/views/admin/post/CPostView.tsx
index e2a4ceb..80f48b6 100644
--- a/src/components/views/admin/post/CPostView.tsx
+++ b/src/components/views/admin/post/CPostView.tsx
@@ -38,16 +38,14 @@ export function CPostView({
posts: parseStateHook(useState(posts)),
editor: parseStateHook(useState(initEditorState)),
};
-
+ // render out the post table
return (
- <>
-
- >
+
);
}
diff --git a/src/components/views/admin/post/PostView.tsx b/src/components/views/admin/post/PostView.tsx
index ad30896..ba9756c 100644
--- a/src/components/views/admin/post/PostView.tsx
+++ b/src/components/views/admin/post/PostView.tsx
@@ -30,14 +30,6 @@ export async function PostView(props: Props) {
"UpdatedAt",
];
- const actions: PostServerActions = {
- deletePost: deletePost,
- getPosts: getPostsWithBucketsAndProject,
- getProjects: getProjects,
- savePost: updatePost,
- // uploadAttachment:tryCreateAttachment
- };
-
const posts: GetPostsAttributes[] | undefined = handleActionResult(
await getPostsWithBucketsAndProject()
);
@@ -52,7 +44,12 @@ export async function PostView(props: Props) {
posts={posts ? posts : []}
projects={projects}
headings={headings}
- actions={actions}
+ actions={{
+ deletePost: deletePost,
+ getPosts: getPostsWithBucketsAndProject,
+ getProjects: getProjects,
+ savePost: updatePost
+ }}
/>
diff --git a/src/components/views/admin/project/ProjectView.tsx b/src/components/views/admin/project/ProjectView.tsx
index d8e8e64..e1d2581 100644
--- a/src/components/views/admin/project/ProjectView.tsx
+++ b/src/components/views/admin/project/ProjectView.tsx
@@ -1,6 +1,6 @@
cache: "no-store";
-import { ReactNode, useEffect } from "react";
+import { ReactNode } from "react";
import EntityManagementTable from "../../../components/client/EntityManagementTable";
import PostTable from "@/components/client/admin/PostTable";
import {
diff --git a/src/lib/swagger.ts b/src/lib/swagger.ts
index 23af113..5146a81 100644
--- a/src/lib/swagger.ts
+++ b/src/lib/swagger.ts
@@ -1,4 +1,4 @@
-//@ts-ignore
+// @ts-ignore
import { createSwaggerSpec } from "next-swagger-doc";
export const getApiDocs = async () => {
diff --git a/src/models/DBState.ts b/src/models/DBState.ts
index 0ada976..5495d97 100644
--- a/src/models/DBState.ts
+++ b/src/models/DBState.ts
@@ -10,10 +10,11 @@ import {
HasOne,
UpdatedAt,
CreatedAt,
+ Table,
} from '@sequelize/core/decorators-legacy';
import { SqliteDialect } from '@sequelize/sqlite3';
-
+@Table({tableName: "DBStates"})
export class DBState extends Model, InferCreationAttributes>{
@Attribute(DataTypes.INTEGER)
diff --git a/src/models/Project.ts b/src/models/Project.ts
index ac03e57..2986586 100644
--- a/src/models/Project.ts
+++ b/src/models/Project.ts
@@ -20,7 +20,7 @@ export class Project extends Model<
> {
@Attribute(DataTypes.INTEGER)
@PrimaryKey
- @Unique
+ // @Unique
@AutoIncrement
declare id: CreationOptional;
@Attribute(DataTypes.STRING)
diff --git a/src/models/index.ts b/src/models/index.ts
index 536255e..0292f6b 100644
--- a/src/models/index.ts
+++ b/src/models/index.ts
@@ -25,7 +25,7 @@ export * from './UserPerms';
export const sequelize = new Sequelize({
dialect: SqliteDialect,
- storage: 'db.sqlite',
+ storage: './db/db.sqlite',
models: [Auth, Attachment, Bucket, DBState, Post, PostBucket, PostTag, Project, Tag, User, UserPerms],
});
diff --git a/src/providers/authprovider.tsx b/src/providers/authprovider.tsx
new file mode 100644
index 0000000..456baca
--- /dev/null
+++ b/src/providers/authprovider.tsx
@@ -0,0 +1,14 @@
+import { Auth, User } from "@/models";
+import { Attributes } from "@sequelize/core";
+import { Context, createContext } from "react";
+
+
+export type AuthContextProviderProps = {
+ auth?: Attributes
+ user?: Attributes
+}
+
+let p: AuthContextProviderProps = {}
+
+export const AuthContext: Context = createContext(p);
+
diff --git a/src/providers/providers.tsx b/src/providers/contextproviders.tsx
similarity index 58%
rename from src/providers/providers.tsx
rename to src/providers/contextproviders.tsx
index b835d95..4e76164 100644
--- a/src/providers/providers.tsx
+++ b/src/providers/contextproviders.tsx
@@ -3,23 +3,14 @@
import { Auth, User } from "@/models";
import { ReactNode, createContext } from "react";
import { Attributes, InferAttributes } from "@sequelize/core";
+import { AuthContext } from "./authprovider";
-
-export type AuthProps = {
- auth?: Attributes
- user?: Attributes
-}
-
-let p: AuthProps = {}
-
-export const AuthContext = createContext(p);
-
-interface Props {
+interface ProvidersProps {
children?: ReactNode;
params?: any;
-}
+}
-export default function Providers(props:Props){
+export default function ContextProviders(props:ProvidersProps){
return (
{props.children}
)
diff --git a/src/providers/index.ts b/src/providers/index.ts
new file mode 100644
index 0000000..f1e2c1b
--- /dev/null
+++ b/src/providers/index.ts
@@ -0,0 +1,2 @@
+export * from './authprovider';
+export * from './contextproviders';
diff --git a/src/util/getAPIEnv.ts b/src/util/api/getAPIEnv.ts
similarity index 59%
rename from src/util/getAPIEnv.ts
rename to src/util/api/getAPIEnv.ts
index d38702c..af1a412 100644
--- a/src/util/getAPIEnv.ts
+++ b/src/util/api/getAPIEnv.ts
@@ -1,10 +1,9 @@
'server only';
-// import Auth from "./Auth";
-export function getAPIEnv() {
+export async function getAPIEnv() {
return {
'schema': process.env.API_SCHEMA,
'host': process.env.API_HOST,
'port': process.env.API_PORT,
- 'basepath': process.env.API_BASEPATH
+ 'basepath': process.env.API_BASEPATH,
};
}
diff --git a/src/util/api/index.ts b/src/util/api/index.ts
index d1f5898..08e4369 100644
--- a/src/util/api/index.ts
+++ b/src/util/api/index.ts
@@ -1,2 +1,4 @@
export * from './error';
+export * from './getAPIEnv';
+export * from './runapiaction';
export * from './user';
diff --git a/src/util/api/runapiaction.ts b/src/util/api/runapiaction.ts
new file mode 100644
index 0000000..4c85e4e
--- /dev/null
+++ b/src/util/api/runapiaction.ts
@@ -0,0 +1,19 @@
+import { NextApiResponse } from "next";
+import { APIError } from "./error";
+
+export type APIRequest = (request:Request)=>Promise;
+
+export async function runApiAction(c:APIRequest,request:Request){
+ try{
+ return await c(request);
+ }
+ catch(e){
+ if (e instanceof APIError){
+ return new Response(e.info.responseText,{status:e.info.status});
+ console.log("responded");
+ }
+ else{
+ throw e;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/util/Cookies.ts b/src/util/cookies/Cookies.ts
similarity index 100%
rename from src/util/Cookies.ts
rename to src/util/cookies/Cookies.ts
diff --git a/src/util/cookies/index.ts b/src/util/cookies/index.ts
new file mode 100644
index 0000000..13d986b
--- /dev/null
+++ b/src/util/cookies/index.ts
@@ -0,0 +1,2 @@
+export * from './Cookies';
+export * from './parseSetCookie';
diff --git a/src/util/parseSetCookie.ts b/src/util/cookies/parseSetCookie.ts
similarity index 100%
rename from src/util/parseSetCookie.ts
rename to src/util/cookies/parseSetCookie.ts
diff --git a/src/util/DeepPartial.ts b/src/util/deeppartial.ts
similarity index 100%
rename from src/util/DeepPartial.ts
rename to src/util/deeppartial.ts
diff --git a/src/util/gens.ts b/src/util/gens.ts
deleted file mode 100644
index b1a03f7..0000000
--- a/src/util/gens.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-
-class Gens{
-
- public static loremipsum():String
- {
- return 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer egestas eros a imperdiet ultrices. Maecenas tincidunt tristique dolor, vitae dignissim ligula faucibus sit amet. Ut hendrerit elit eu elit molestie, vel consectetur leo accumsan. Phasellus ex mi, dignissim at aliquam at, rutrum eget mi. Curabitur pellentesque auctor nulla sed pulvinar. Maecenas scelerisque orci at sem finibus tincidunt. Mauris viverra pulvinar nibh. Etiam ornare purus leo, at cursus elit ornare nec. Suspendisse potenti. Sed nisl libero, sollicitudin vitae dignissim sit amet, laoreet sit amet odio. Duis rhoncus felis ut erat facilisis, vitae rutrum odio sollicitudin. Praesent et scelerisque eros. Praesent laoreet eu orci ut blandit. Morbi dapibus nibh urna, eget blandit quam aliquet vitae. Nulla quam metus, volutpat et vulputate vel, viverra sed diam.'
- }
-
-}
-export default Gens;
\ No newline at end of file
diff --git a/src/util/index.ts b/src/util/index.ts
index 9f0f006..5be0227 100644
--- a/src/util/index.ts
+++ b/src/util/index.ts
@@ -1,10 +1,5 @@
-export * from './api';
export * from './auth';
-export * from './Cookies';
-export * from './DeepPartial';
-export * from './gens';
-export * from './getAPIEnv';
-export * from './parseSetCookie';
+export * from './cookies';
+export * from './deeppartial';
export * from './state';
-export * from './url';
-export * from './utils';
+export * from './strings';
diff --git a/src/util/strings/index.ts b/src/util/strings/index.ts
new file mode 100644
index 0000000..1bffea4
--- /dev/null
+++ b/src/util/strings/index.ts
@@ -0,0 +1,2 @@
+export * from './loremipsum';
+export * from './truncateString';
\ No newline at end of file
diff --git a/src/util/strings/loremipsum.ts b/src/util/strings/loremipsum.ts
new file mode 100644
index 0000000..8f31208
--- /dev/null
+++ b/src/util/strings/loremipsum.ts
@@ -0,0 +1,6 @@
+
+export function loremipsum():String
+{
+ return 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer egestas eros a imperdiet ultrices. Maecenas tincidunt tristique dolor, vitae dignissim ligula faucibus sit amet. Ut hendrerit elit eu elit molestie, vel consectetur leo accumsan. Phasellus ex mi, dignissim at aliquam at, rutrum eget mi. Curabitur pellentesque auctor nulla sed pulvinar. Maecenas scelerisque orci at sem finibus tincidunt. Mauris viverra pulvinar nibh. Etiam ornare purus leo, at cursus elit ornare nec. Suspendisse potenti. Sed nisl libero, sollicitudin vitae dignissim sit amet, laoreet sit amet odio. Duis rhoncus felis ut erat facilisis, vitae rutrum odio sollicitudin. Praesent et scelerisque eros. Praesent laoreet eu orci ut blandit. Morbi dapibus nibh urna, eget blandit quam aliquet vitae. Nulla quam metus, volutpat et vulputate vel, viverra sed diam.'
+}
+
diff --git a/src/util/strings/truncateString.ts b/src/util/strings/truncateString.ts
new file mode 100644
index 0000000..c741544
--- /dev/null
+++ b/src/util/strings/truncateString.ts
@@ -0,0 +1,7 @@
+export function truncateString(str:string = '', num:number = 255) {
+ if (str.length > num) {
+ return str.slice(0, num) + "...";
+ } else {
+ return str;
+ }
+}
\ No newline at end of file
diff --git a/src/util/url/urlConstructor.ts b/src/util/url/urlConstructor.ts
index ce1ddb4..618c8a4 100644
--- a/src/util/url/urlConstructor.ts
+++ b/src/util/url/urlConstructor.ts
@@ -1,12 +1,12 @@
'use server'
-import { getAPIEnv } from "../getAPIEnv";
+import { getAPIEnv } from "../api/getAPIEnv";
-export function constructAPIUrl(endpoint:string){
- const { schema, host, port, basepath } = getAPIEnv();
+export async function constructAPIUrl(endpoint:string){
+ const { schema, host, port, basepath } = await getAPIEnv();
return `${schema}://${host}:${port}/${basepath}/${endpoint}`
}
-export function constructUrl(endpoint:string){
- const { schema, host, port, basepath } = getAPIEnv();
+export async function constructUrl(endpoint:string){
+ const { schema, host, port, basepath } = await getAPIEnv();
return `${schema}://${host}:${port}/${endpoint}`
}1
\ No newline at end of file
diff --git a/src/util/utils.ts b/src/util/utils.ts
deleted file mode 100644
index c60ebce..0000000
--- a/src/util/utils.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-'server only'
-import { ReactNode } from "react";
-import Gens from "./gens";
-function truncateString(str:string = '', num:number = 255) {
- if (str.length > num) {
- return str.slice(0, num) + "...";
- } else {
- return str;
- }
-}
-
-
-export { Gens, truncateString }
-export const aifa = (a: ReactNode, b: ReactNode) => (a ? a : b);