diff --git a/APIDOCS.md b/APIDOCS.md new file mode 100644 index 0000000..88e31a4 --- /dev/null +++ b/APIDOCS.md @@ -0,0 +1,73 @@ +# API documentation of Akf-forum + + +Akf-forum has got an API for other clients etc. + +You can find an example in apitest.py. + +## Authorization +You need this headers for send request to API: +```jsonc +{ + "username": "testUser", + "password": "testPassword" +} +``` + + +## How to request? + +### Request type: + `GET /api/action/id` + +### "action" types: +- `message` + +(for now, only message.) + +### "id": +ID for action type. + + +### Example request: +```GET /api/message/1``` + +#### Example API Output: + ```json + { + "status": 200, + "result": + { + "content": "First message", + "time": 1647178873587, + "deleted": false, + "edited": false, + "react": {}, + "id": 1, + "author": { + "name": "ForumcuCocuk", + "avatar": "/images/guest.png", + "time": 1647177723873, + "admin": true, + "id": 1 + }, + "thread": { + "author": { + "name": "Akif9748", + "avatar": "/images/guest.png", + "time": 1647177705200, + "admin": true, + "id": 0 + }, + "title": "First Thread", + "messages": [0, 1], + "time": 1647178870047, + "deleted": false, + "id": 0 + } + } +} + + ``` + + diff --git a/README.md b/README.md index 8fb5526..cea3308 100644 --- a/README.md +++ b/README.md @@ -8,14 +8,16 @@ A forum script written in Node.js. - Write `npm i` to install **dependencies**. - Write `npm restart` for reset database, and `npm start` for run it. +## API +Akf-forum has got an API for other clients etc. You can test api with run apitest.py. +And, you can learn informations about API in `APIDOCS.md`. + ## Credits -* [Akif9748](https://github.com/Akif9748) - Project owner +* [Akif9748](https://github.com/Akif9748) - Project owner, main developer * [Camroku](https://github.com/Camroku) - Made stylesheets - - ## To Do: -- Admin panel, delete, edit messages. +- Better method for params in URL ## Roadmap - [x] User @@ -26,22 +28,21 @@ A forum script written in Node.js. - [x] Message count - [x] Delete User - [ ] Singature & About me + - [ ] Edit user - [ ] Messages - [x] Send message - [x] Delete message - [ ] Edit message - [x] React message -- [ ] Forums - - [ ] Category system - - [ ] Create category - - [ ] Delete category - - [ ] Edit category - - [ ] Move category +- [ ] Threads + - [ ] Edit it! + - [ ] Delete it! - [ ] Other - - [ ] API - - [ ] Other client for forum via API - - [ ] Footer... - - [ ] Search + - [x] API + - [x] Other client for forum via API + - [ ] Footer of the site + - [ ] Multiple theme support + - [ ] Search - [x] New Thread theme, better render for messages ## Image: ![image](https://user-images.githubusercontent.com/70021050/158060900-7384d394-cad7-4f73-94ad-7c8bd108ac44.png) diff --git a/api/index.js b/api/index.js new file mode 100644 index 0000000..7ede19d --- /dev/null +++ b/api/index.js @@ -0,0 +1,81 @@ +const { User, Message, Thread } = require("../classes"); +const db = require("quick.db"); + + +class ApiResponse { + constructor(status, result) { + this.status = status; + this.result = result; + } +} + +const { request, response } = require("express"); + +/** + * For intellisense + * @param {request} req + * @param {response} res + */ + +module.exports = (req, res) => { + + const error = (status, error) => + res.status(status).json(new ApiResponse(403, { error })) + + + /** + * AUTH TYPE: + + headers: + { + username: "Username for client", + password: "Password of selected username for client" + } + + */ + + const { username = null, password = null } = req.headers; + + if (!username || !password) + return error(403, "Headers are missing") + + const user = db.get("secret." + username); + + if (!user) + return error(403, "We have not got any user has got this name") + + if (user.key !== password) + return error(403, 'Incorrect Password!') + + + + /** + * REQUEST TYPE: + * GET /api/action/id + * + * @example message action: + * GET /api/message/0 + * + */ + const { action } = req.params; + + switch (action) { + case "message": + const { id = null } = req.params; + if (!id) return error(403, "Missing id in query") + const message = new Message().getId(id); + + if (!message || message.deleted) return error(403, "We have not got any message declared as this id."); + + res.status(200).json(new ApiResponse(200, message)); + + break; + + default: + return error(403, "Missing/undefined param: action"); + } + + + +} + diff --git a/apitest.py b/apitest.py new file mode 100644 index 0000000..f42c984 --- /dev/null +++ b/apitest.py @@ -0,0 +1,50 @@ +import requests + +# Headers for login to Akf-forum +headers = { + "username": "testUser", + "password": "testPassword" +} + + +r = requests.get("http://localhost:3000/api/message/1/", headers=headers) + +print(r.json()) + +example_response = { + "status": 200, + "result": + { # content of message + "content": "a", + # author of message + "author": { + "name": "ForumcuCocuk", + "avatar": "/images/guest.png", + "time": 1647177723873, + "admin": True, + "id": 1 + }, + # UNIX Timestamp of message + "time": 1647178873587, + # thread information of message + "thread": { + "author": { + "name": "ForumcuCocuk", + "avatar": "/images/guest.png", + "time": 1647177723873, + "admin": True, + "id": 1 + }, + "title": "My", + "messages": [0], # ids of messages + "time": 1647178870047, + "deleted": False, + "id": "0" + }, + # Other informations about message + "deleted": False, + "edited": False, + "react": {}, + "id": "1" + } +} diff --git a/classes/index.js b/classes/index.js index eb670ca..5ee37f7 100644 --- a/classes/index.js +++ b/classes/index.js @@ -1,6 +1,9 @@ -const Message = require("./message") -const Thread = require("./thread") -const User = require("./user") -const React = require("./react") +const Message = require("./message"); +const Thread = require("./thread"); +const User = require("./user"); +const React = require("./react"); -module.exports = { Message, Thread, User, React } \ No newline at end of file +/** + * Classes for akf-forum; + */ +module.exports = { Message, Thread, User, React }; \ No newline at end of file diff --git a/classes/message.js b/classes/message.js index ad7958d..1cab40b 100644 --- a/classes/message.js +++ b/classes/message.js @@ -17,10 +17,10 @@ module.exports = class Message { this.react = react; } getId(id = this.id) { - const message = db.get("messages" ).find(msg => msg.id == id); + const message = db.get("messages").find(msg => msg.id == id); if (!message) return null; - this.id = id; + this.id = Number(id); const { content, author, thread = new Thread(), time = new Date().getTime(), deleted = false, edited = false, react = {} } = message; this.content = content; this.thread = thread; diff --git a/classes/thread.js b/classes/thread.js index 6acff78..53eb6fc 100644 --- a/classes/thread.js +++ b/classes/thread.js @@ -19,7 +19,7 @@ module.exports = class Thread { getId(id = this.id) { const thread = db.get("threads").find(t => t.id == id); if (!thread) return null; - this.id = id; + this.id = Number(id); const { title, author, messages = [], time = new Date().getTime(), deleted = false } = thread; this.title = title this.author = author diff --git a/index.js b/index.js index 0fa4bfe..e96ced2 100644 --- a/index.js +++ b/index.js @@ -18,13 +18,19 @@ app.set("view engine", "ejs"); //Temp: app.get("/", (req, res) => res.redirect("/index")); +/** + * API: + */ +app.get("/api/:action/:id", require("./api")); + for (const type of fs.readdirSync("./routes")) for (const file of fs.readdirSync("./routes/" + type)) app[type](`/${file.replace(".js", "")}*`, require(`./routes/${type}/${file}`)) app.get('*', (req, res) => error(res, 404, "We have not got this page.")); -app.post('*', (req, res) => error(res, 404, "We have not got this page.")); +app.post('*', (req, res) => error(res, 404, "We have not got this page.")); const port = process.env.PORT || 3000; -app.listen(port, () => console.log("SERVER ON PORT:", port)); \ No newline at end of file +app.listen(port, () => console.log("SERVER ON PORT:", port)); + diff --git a/package-lock.json b/package-lock.json index 4708c37..dca9e35 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,11 +1,11 @@ { - "name": "karum", + "name": "akf-lang", "version": "2.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "karum", + "name": "akf-lang", "version": "2.1.0", "license": "GPL-3.0-or-later", "dependencies": { diff --git a/package.json b/package.json index 72afc84..d276369 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "karum", + "name": "akf-lang", "version": "2.1.0", "description": "A forum script written in Node.js", "main": "index.js", @@ -9,7 +9,7 @@ }, "repository": { "type": "git", - "url": "git+https://github.com/Akif9748/karum.git" + "url": "git+https://github.com/Akif9748/akf-lang.git" }, "author": "Akif9748", "contributors": [ @@ -17,9 +17,9 @@ ], "license": "GPL-3.0-or-later", "bugs": { - "url": "https://github.com/Akif9748/karum/issues" + "url": "https://github.com/Akif9748/akf-lang/issues" }, - "homepage": "https://github.com/Akif9748/karum#readme", + "homepage": "https://github.com/Akif9748/akf-lang#readme", "dependencies": { "body-parser": "^1.19.2", "ejs": "^3.1.6", diff --git a/routes/get/admin.js b/routes/get/admin.js index f536435..af93712 100644 --- a/routes/get/admin.js +++ b/routes/get/admin.js @@ -1,5 +1,4 @@ const { User } = require("../../classes/index"); -const { get } = require("quick.db"); const error = require("../../errors/error.js"); module.exports = (req, res) => { diff --git a/routes/get/userEdit.js b/routes/get/userEdit.js new file mode 100644 index 0000000..300238a --- /dev/null +++ b/routes/get/userEdit.js @@ -0,0 +1,9 @@ +const { User } = require("../../classes/index"); +module.exports = (req, res) => { + + if (!req.session.loggedin) return res.redirect('/login'); + + const user = new User().getId(req.session.userid); + res.render("userEdit", { user }) + +} \ No newline at end of file diff --git a/routes/post/login.js b/routes/post/login.js index 08ad768..5a1fa04 100644 --- a/routes/post/login.js +++ b/routes/post/login.js @@ -1,6 +1,6 @@ const db = require("quick.db"); const error = require("../../errors/error.js") -const { User, Message } = require("../../classes/index"); +const { User } = require("../../classes/index"); module.exports = (req, res) => { req.session.loggedin = false; @@ -12,19 +12,19 @@ module.exports = (req, res) => { const user = db.get("secret." + username) if (user) { // Authenticate the user - if (user.key !== password) return error(res, 404, 'Incorrect Password!') - if (new User().getName(username).deleted) return error(res, 404, 'Incorrect Username and/or Password!') + if (user.key !== password) return error(res, 403, 'Incorrect Password!') + if (new User().getName(username).deleted) return error(res, 403, 'Incorrect Username and/or Password!') req.session.loggedin = true; req.session.username = username; req.session.userid = user.id; res.redirect('/'); } else - error(res, 404, 'Incorrect Username and/or Password!') + error(res, 403, 'Incorrect Username and/or Password!') } else - error(res, 404, "You forgot entering some values") + error(res, 403, "You forgot entering some values") diff --git a/views/admin.ejs b/views/admin.ejs index 6cfed45..673578e 100644 --- a/views/admin.ejs +++ b/views/admin.ejs @@ -5,8 +5,8 @@ - Main page! - + Admin panel! + diff --git a/views/index.ejs b/views/index.ejs index bc9c867..f533c25 100644 --- a/views/index.ejs +++ b/views/index.ejs @@ -6,7 +6,7 @@ Main page! - + diff --git a/views/login.ejs b/views/login.ejs index 8e5bc7b..a091859 100644 --- a/views/login.ejs +++ b/views/login.ejs @@ -6,7 +6,7 @@ LOGIN - + diff --git a/views/openThread.ejs b/views/openThread.ejs index 9c493e6..7718257 100644 --- a/views/openThread.ejs +++ b/views/openThread.ejs @@ -6,7 +6,7 @@ Open Thread - + diff --git a/views/register.ejs b/views/register.ejs index 8a0490e..ee28b07 100644 --- a/views/register.ejs +++ b/views/register.ejs @@ -6,7 +6,7 @@ Register - + diff --git a/views/thread.ejs b/views/thread.ejs index 1209b43..4abca08 100644 --- a/views/thread.ejs +++ b/views/thread.ejs @@ -8,7 +8,7 @@ <%= thread.title %> - + diff --git a/views/threads.ejs b/views/threads.ejs index 8f5fef1..1e30234 100644 --- a/views/threads.ejs +++ b/views/threads.ejs @@ -5,8 +5,8 @@ - Main page! - + Threads! + diff --git a/views/userEdit.ejs b/views/userEdit.ejs new file mode 100644 index 0000000..7a6f395 --- /dev/null +++ b/views/userEdit.ejs @@ -0,0 +1,50 @@ + + + + + + + + Edit profile + + + + + + + + + +
+ + + + +

> <%= user.name %> + alt=<%= user.name %>> +

+
+ + + +
+ + + +

This page is not ready.

+
+ + + + \ No newline at end of file