You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dick/src/utils/middleware.ts

101 lines
4.2 KiB

V1.1.0 (#24) ## Update Info 🍆 **DICK** v1.1.0 🍆 Our number is getting bigger! Though, I hear size is not what matters but how you use it. So, I am happy to introduce you to a bunch of new stuff within the front end! 🔀 **UPDATING** Updating your instance should be easy, unless you already edited the code base, at that point your on your own. If you have a direct clone of the master of the current 1.0.2(old master) branch, then all you need to do is 1. Browse to your DICK folder 2. Run `git pull` to pull new changes 3. Run `npm i` to install new dependancies 4. Delete the `dist` folder 5. Start DICK using `npm start` 6. Enjoy > **Note** > If you load your instance and styling seems wrong, please clear your browsers cache, and reload the page. > **Note** > The first user to log into your DICK WebUI will be marked as the instance admin. You can change which users are admin by editing the user database file located at `/src/database/users.json`. This file will only appear once you've started your instance for the first time. ✏️ **CHANGELOG** ```diff ADDITIONS + Admin Dashboard > This page will be where system administrators can view their syatem settings and stats! + Database > Added DICK database, inside JSON files with management utils. + Added new app settings page to Admin Dashboard > This will allow administrators to customize their instance on the fly without having to edit the codebase. White labeling! + Added user list to Admin Dashboard > This allows administrators to view which users are registered in their ASS currently, and their roles set. You can also create new users from this page. (There are a lot of hidden divs in this page so imstance admins can add extra code to dick to enable stuff like deletion of users) + Registrations > Administrators can toggle registrations into their ASS from their DICK UI via the /register page! + Captcha > By default, when a user gets login information wrong they will be forwarded to a Rick Roll. Now you can add a hCaptcha site key to DICK to enable hCaptcha for your login and register public pages! + Added a "default profile picture" > Every users default profile picture. This is planned to be able to be set per user in the future, so users can pick their own seperate from the default. REMOVALS - Removeed STAFF_IDs from codebase. > This means you can remove this CONSTANT from your instance CONSTANTS file, please see the repo's constants example file to see if yours matches it. ``` ```fix CHANGES = Large codebase cleanup = Seperated js for components into their own files based on job = Redid some naming for tailwind colour theme classes to provide proper theming from the tailwind config file = Cleaned up a lot of the utils = Added embed gen page as a hidden extra for devs to add themselves in their own time if they wish (please PR if you achieve this 🤘) = Fixed the flash message warning colours to actually be red or green depending on error/success ``` ## Issues Resolved / Fixes In This Release Resolves #17 , Resolves #14 , Resolves #10 , Resolves #7
2 years ago
import { Response, NextFunction } from "express"
import { Log } from "@callmekory/logger"
import fetch from 'node-fetch'
import { IExtendedRequest } from "../typings/express-ext"
import { checkIfUserExistInDICK, createUserInDICK, getSettingsDatabase, getUserDatabase, getUserDatabaseObj } from "./database"
import { parseAuthFile } from "./assJSONStructure"
import { IUserSettings } from "typings/database"
/**
* Wraps the express route in a function that passes the
* `next` method from the route to the promise's catch
* statement which allows the middleware to catch the
* exception.
*/
export const wrap = async (req: IExtendedRequest, res: Response, next: NextFunction) => {
if (req.user) {
// If the user does not exist in DICKs database yet, we add them
if (await checkIfUserExistInDICK(req.user.username) == false) {
createUserInDICK(req.user.username)
}
// Make sure ASS users stay synced with DICK database
const assUserDatabase = parseAuthFile()
const dickUserDatabase = getUserDatabase()
if(dickUserDatabase.length !== 0){
for (const user of assUserDatabase) {
if (!dickUserDatabase.find((e: IUserSettings) => e.username === user.username)) {
createUserInDICK(user.username)
}
}
}
// Log the page the user navigated to
Log.info(`${req.user.username} navigated to page ${req.path}`)
}
return next()
}
//Express middleware to check captcha token
export const checkCaptcha = async (req: IExtendedRequest, res: Response, next: NextFunction) => {
const database = getSettingsDatabase()
// If captcha is enabled, we verify the captcha
if (database.captchaEnabled) {
// If there is no response for some reason
if(!req.body['h-captcha-response']){
Log.info(`A user submitted a form on the endpoint ${req.path} and failed captcha due to not being able to reach hCaptcha, redirecting back to login page`)
req.flash('error_message', `You failed the captcha due to not being able to reach hCaptcha. Please reach an admin.`)
return res.redirect("/login")
}
// Build payload with secret key and captcha response token from form data with key 'h-captcha-response'
const params = new URLSearchParams()
params.append('secret', database.captchaSecretKey)
params.append('response', req.body['h-captcha-response'])
// Make POST request with data payload to hCaptcha API endpoint
const response = await fetch("https://hcaptcha.com/siteverify", { method: 'POST', body: params })
const data = await response.json()
// Parse JSON from response. Check for success or error codes.
// If not correct, send back to login screen with error
// A missing-input-response means its not getting info from hcaptcha
if (data.success == false){
Log.info(`A user submitted a form on the endpoint ${req.path} and failed captcha due to: ${data['error-codes']}, redirecting back to login page`)
req.flash('error_message', `You failed the captcha due to ${data['error-codes']}. Please try again.`)
return res.redirect("/login")
}
// Else continue as they are verified as human
next()
} else next()
}
// Express middleware to check if username/password match one of the users
// in auth.json
export const authCheck = (req: IExtendedRequest, res: Response, next: NextFunction) => {
if (!req.user) {
Log.info(`A user navigated to page ${req.path} and is not logged in, redirecting to login page`)
req.flash('error_message', 'Please log in to access the requested page')
res.redirect('/login')
} else next()
}
// Express middleware to check if username trying to access the page matches the users
// in CONSTANTS
export const adminCheck = (req: IExtendedRequest, res: Response, next: NextFunction) => {
const user = getUserDatabaseObj(req.user.username)
if (!user) {
Log.info(`A user navigated to page ${req.path} and is not logged in, redirecting to login page`)
req.flash('error_message', 'Please log in to access the requested page')
res.redirect('/login')
}
if (user.role !== 'admin') {
Log.info(`${req.user.username} navigated to page ${req.path} and is not an admin, redirecting to users dashboard`)
res.redirect('/')
} else next()
}