forked from fr/deguapp
		
	Zmena planu
This commit is contained in:
		@@ -1,59 +0,0 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
# @link https://gist.github.com/mattscilipoti/8424018
 | 
			
		||||
#
 | 
			
		||||
# Called by "git push" after it has checked the remote status,
 | 
			
		||||
# but before anything has been pushed.
 | 
			
		||||
#
 | 
			
		||||
# If this script exits with a non-zero status nothing will be pushed.
 | 
			
		||||
#
 | 
			
		||||
# Steps to install, from the root directory of your repo...
 | 
			
		||||
# 1. Copy the file into your repo at `.git/hooks/pre-push`
 | 
			
		||||
# 2. Set executable permissions, run `chmod +x .git/hooks/pre-push`
 | 
			
		||||
# 3. Or, use `rake hooks:pre_push` to install
 | 
			
		||||
#
 | 
			
		||||
# Try a push to master, you should get a message `*** [Policy] Never push code directly to...`
 | 
			
		||||
#
 | 
			
		||||
# The commands below will not be allowed...
 | 
			
		||||
# `git push origin master`
 | 
			
		||||
# `git push --force origin master`
 | 
			
		||||
# `git push --delete origin master`
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
protected_branch='master'
 | 
			
		||||
 | 
			
		||||
policy="\n\n[Policy] Never push code directly to the "$protected_branch" branch! (Prevented with pre-push hook.)\n\n"
 | 
			
		||||
 | 
			
		||||
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
 | 
			
		||||
 | 
			
		||||
push_command=$(ps -ocommand= -p $PPID)
 | 
			
		||||
 | 
			
		||||
is_destructive='force|delete|\-f'
 | 
			
		||||
 | 
			
		||||
will_remove_protected_branch=':'$protected_branch
 | 
			
		||||
 | 
			
		||||
do_exit(){
 | 
			
		||||
  echo -e $policy
 | 
			
		||||
  exit 1
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if [[ $push_command =~ $is_destructive ]] && [ $current_branch = $protected_branch ]; then
 | 
			
		||||
  do_exit
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [[ $push_command =~ $is_destructive ]] && [[ $push_command =~ $protected_branch ]]; then
 | 
			
		||||
  do_exit
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
if [[ $push_command =~ $will_remove_protected_branch ]]; then
 | 
			
		||||
  do_exit
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# Prevent ALL pushes to protected_branch
 | 
			
		||||
if [[ $push_command =~ $protected_branch ]] || [ $current_branch = $protected_branch ]; then
 | 
			
		||||
  do_exit
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
unset do_exit
 | 
			
		||||
 | 
			
		||||
exit 0
 | 
			
		||||
							
								
								
									
										3
									
								
								api/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								api/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +0,0 @@
 | 
			
		||||
node_modules/
 | 
			
		||||
package-lock.json
 | 
			
		||||
*.env
 | 
			
		||||
@@ -1,15 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
	"tabWidth": 4,
 | 
			
		||||
	"useTabs": true,
 | 
			
		||||
	"singleQuote": true,
 | 
			
		||||
	"semi": false,
 | 
			
		||||
	"trailingComma": "none",
 | 
			
		||||
	"jsxSingleQuote": true,
 | 
			
		||||
	"jsxBracketSameLine": true,
 | 
			
		||||
	"printWidth": 200,
 | 
			
		||||
	"bracketSpacing": true,
 | 
			
		||||
	"vueIndentScriptAndStyle": true,
 | 
			
		||||
	"arrowParens": "always",
 | 
			
		||||
	"bracketSameLine": false,
 | 
			
		||||
    "endOfLine": "lf"
 | 
			
		||||
}
 | 
			
		||||
@@ -1 +0,0 @@
 | 
			
		||||
# New Project
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
/beer
 | 
			
		||||
	/add
 | 
			
		||||
	/del
 | 
			
		||||
	/get
 | 
			
		||||
	/edit?
 | 
			
		||||
	/review
 | 
			
		||||
		/add
 | 
			
		||||
		/del
 | 
			
		||||
		/get
 | 
			
		||||
		/edit?
 | 
			
		||||
 | 
			
		||||
/user
 | 
			
		||||
	/add
 | 
			
		||||
	/del
 | 
			
		||||
	/get
 | 
			
		||||
	/login
 | 
			
		||||
	/signup
 | 
			
		||||
	/edit?
 | 
			
		||||
 | 
			
		||||
review kriteria:
 | 
			
		||||
 - pena
 | 
			
		||||
  - 3 stupne hodnoceni
 | 
			
		||||
 - horkost-sladkost
 | 
			
		||||
  - slider
 | 
			
		||||
 - kyselost
 | 
			
		||||
  - T/F
 | 
			
		||||
 - packaging
 | 
			
		||||
  - 5 stupnu hodnoceni
 | 
			
		||||
 - dal bych si znovu
 | 
			
		||||
  - T/F
 | 
			
		||||
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "project_name": "deguapp-api",
 | 
			
		||||
  "lang": "ts",
 | 
			
		||||
  "author": "Filip Rojek",
 | 
			
		||||
  "database": {
 | 
			
		||||
    "db": "mysql",
 | 
			
		||||
    "orm": "sequelize"
 | 
			
		||||
  },
 | 
			
		||||
  "website": "http://filiprojek.cz",
 | 
			
		||||
  "email": "filip@filiprojek.cz",
 | 
			
		||||
  "version": "3.0.5"
 | 
			
		||||
}
 | 
			
		||||
@@ -1,73 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "deguapp-api",
 | 
			
		||||
  "version": "1.0.0",
 | 
			
		||||
  "description": "",
 | 
			
		||||
  "main": "dist/server.js",
 | 
			
		||||
  "private": "true",
 | 
			
		||||
  "keywords": [],
 | 
			
		||||
  "author": "Filip Rojek <filip@filiprojek.cz> (http://filiprojek.cz)",
 | 
			
		||||
  "repository": "github:username/repo",
 | 
			
		||||
  "license": "ISC",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
    "start": "node dist/server.js",
 | 
			
		||||
    "start:dev": "nodemon src/server.ts",
 | 
			
		||||
    "test": "jest",
 | 
			
		||||
    "clean": "rimraf dist/*",
 | 
			
		||||
    "copy-assets": "npx ts-node src/utils/copyAssets",
 | 
			
		||||
    "tsc": "tsc -p .",
 | 
			
		||||
    "build": "npm-run-all clean tsc copy-assets",
 | 
			
		||||
    "format": "npx prettier --write ."
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "colors": "1.4.0",
 | 
			
		||||
    "cookie-parser": "^1.4.5",
 | 
			
		||||
    "cors": "^2.8.5",
 | 
			
		||||
    "dotenv": "^8.2.0",
 | 
			
		||||
    "ejs": "^3.1.6",
 | 
			
		||||
    "express": "^4.17.1",
 | 
			
		||||
    "express-validator": "^6.14.2",
 | 
			
		||||
    "fs-extra": "^10.0.0",
 | 
			
		||||
    "jsonwebtoken": "^8.5.1",
 | 
			
		||||
    "mongoose": "^5.12.3",
 | 
			
		||||
    "pg": "^8.7.1",
 | 
			
		||||
    "pg-hstore": "^2.3.4",
 | 
			
		||||
    "sequelize": "^6.15.0"
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@types/cookie-parser": "^1.4.2",
 | 
			
		||||
    "@types/cors": "^2.8.10",
 | 
			
		||||
    "@types/ejs": "^3.0.6",
 | 
			
		||||
    "@types/express": "^4.17.11",
 | 
			
		||||
    "@types/fs-extra": "^9.0.12",
 | 
			
		||||
    "@types/jest": "^27.5.2",
 | 
			
		||||
    "@types/jsonwebtoken": "^8.5.8",
 | 
			
		||||
    "@types/mongoose": "^5.10.5",
 | 
			
		||||
    "@types/morgan": "^1.9.2",
 | 
			
		||||
    "@types/node": "^14.14.41",
 | 
			
		||||
    "@types/shelljs": "^0.8.9",
 | 
			
		||||
    "jest": "^27.0.6",
 | 
			
		||||
    "npm-run-all": "^4.1.5",
 | 
			
		||||
    "rimraf": "^3.0.2",
 | 
			
		||||
    "shelljs": "^0.8.4",
 | 
			
		||||
    "ts-jest": "^27.1.5",
 | 
			
		||||
    "ts-node": "^10.8.1",
 | 
			
		||||
    "typescript": "^4.2.4",
 | 
			
		||||
    "morgan": "^1.10.0"
 | 
			
		||||
  },
 | 
			
		||||
  "jest": {
 | 
			
		||||
    "preset": "ts-jest",
 | 
			
		||||
    "testEnvironment": "node"
 | 
			
		||||
  },
 | 
			
		||||
  "nodemonConfig": {
 | 
			
		||||
    "ignore": [
 | 
			
		||||
      "**/*.test.ts",
 | 
			
		||||
      "**/*.spec.ts",
 | 
			
		||||
      ".git",
 | 
			
		||||
      "node_modules"
 | 
			
		||||
    ],
 | 
			
		||||
    "watch": [
 | 
			
		||||
      "src"
 | 
			
		||||
    ],
 | 
			
		||||
    "ext": "ts, js"
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
cp .githooks/* .git/hooks
 | 
			
		||||
 | 
			
		||||
echo "hooks have been copied"
 | 
			
		||||
@@ -1,26 +0,0 @@
 | 
			
		||||
# General
 | 
			
		||||
APP_PORT = 6060
 | 
			
		||||
APP_HOSTNAME = 'localhost'
 | 
			
		||||
APP_HOST = 'http://localhost:8080' # frontend url
 | 
			
		||||
 | 
			
		||||
# Timezone
 | 
			
		||||
TZ = 'Europe/Prague'
 | 
			
		||||
 | 
			
		||||
CORS_WHITELIST = http://172.15.46.21:8080;http://192.168.0.1:8080
 | 
			
		||||
JWT_SECRET = ''
 | 
			
		||||
 | 
			
		||||
# MongoDB
 | 
			
		||||
DB_URI = 'mongodb://username:password@localhost:27017/database?authSource=admin'
 | 
			
		||||
 | 
			
		||||
# PostgreSQL
 | 
			
		||||
DB_PORT = 5432
 | 
			
		||||
DB_HOST = '127.0.0.1'
 | 
			
		||||
DB_USERNAME = ''
 | 
			
		||||
DB_PASSWORD = ''
 | 
			
		||||
DB_DATABASE = ''
 | 
			
		||||
 | 
			
		||||
# SMTP
 | 
			
		||||
SMTP_HOST = ''
 | 
			
		||||
SMTP_USER = ''
 | 
			
		||||
SMTP_PASS = ''
 | 
			
		||||
SMTP_FROM = ''
 | 
			
		||||
@@ -1,42 +0,0 @@
 | 
			
		||||
import express from 'express'
 | 
			
		||||
import morgan from 'morgan'
 | 
			
		||||
import path from 'path'
 | 
			
		||||
import cors from 'cors'
 | 
			
		||||
import cookieParser from 'cookie-parser'
 | 
			
		||||
import { router as routes } from './routes'
 | 
			
		||||
import { router as middlewares } from './middlewares'
 | 
			
		||||
import env from './config/environment'
 | 
			
		||||
 | 
			
		||||
export let corsWhitelist: Array<string>
 | 
			
		||||
if (env.CORS_WHITELIST != 'undefined') {
 | 
			
		||||
	corsWhitelist = [...['http://localhost:8080', 'http://localhost:6040'], ...env.CORS_WHITELIST.split(';')]
 | 
			
		||||
} else {
 | 
			
		||||
	corsWhitelist = ['http://localhost:8080', 'http://localhost:6040']
 | 
			
		||||
}
 | 
			
		||||
const corsOptions = {
 | 
			
		||||
	origin: function (origin: any, callback: any) {
 | 
			
		||||
		if (!origin || corsWhitelist.indexOf(origin) !== -1) {
 | 
			
		||||
			callback(null, true)
 | 
			
		||||
		} else {
 | 
			
		||||
			callback(new Error('Not allowed by CORS'))
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	optionsSuccessStatus: 200,
 | 
			
		||||
	credentials: true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const app = express()
 | 
			
		||||
 | 
			
		||||
// Middlewares
 | 
			
		||||
app.use(middlewares)
 | 
			
		||||
app.set('view engine', 'ejs')
 | 
			
		||||
app.set('views', path.join(__dirname, 'views'))
 | 
			
		||||
app.use(cors(corsOptions))
 | 
			
		||||
app.use(morgan('dev'))
 | 
			
		||||
app.use(express.urlencoded({ extended: true }))
 | 
			
		||||
app.use(express.json())
 | 
			
		||||
app.use(express.static(path.join(__dirname, 'public')))
 | 
			
		||||
app.use(cookieParser())
 | 
			
		||||
 | 
			
		||||
// Routes
 | 
			
		||||
app.use(routes)
 | 
			
		||||
@@ -1,49 +0,0 @@
 | 
			
		||||
import mongoose from 'mongoose'
 | 
			
		||||
import env from './environment'
 | 
			
		||||
import { Err, Succ } from '../services/globalService'
 | 
			
		||||
import db from './sequelize.config'
 | 
			
		||||
 | 
			
		||||
// MongoDB
 | 
			
		||||
const dbURI: string = env.DB_URI
 | 
			
		||||
function connect() {
 | 
			
		||||
	if (!env.NORK.database) {
 | 
			
		||||
		new Err(500, 'no database is in norkcfg.json')
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (env.NORK.database.orm == 'mongoose') {
 | 
			
		||||
		mongoose
 | 
			
		||||
			.connect(dbURI, {
 | 
			
		||||
				useNewUrlParser: true,
 | 
			
		||||
				useUnifiedTopology: true,
 | 
			
		||||
				useCreateIndex: true
 | 
			
		||||
			})
 | 
			
		||||
			.then(() => {
 | 
			
		||||
				new Succ(200, 'connected to db')
 | 
			
		||||
				return true
 | 
			
		||||
			})
 | 
			
		||||
			.catch((err: any) => {
 | 
			
		||||
				new Err(500, err)
 | 
			
		||||
				return false
 | 
			
		||||
			})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (env.NORK.database.orm == 'sequelize') {
 | 
			
		||||
		db.sync()
 | 
			
		||||
			.then(() => {
 | 
			
		||||
				new Succ(200, 'connected to db')
 | 
			
		||||
				return true
 | 
			
		||||
			})
 | 
			
		||||
			.catch((err: any) => {
 | 
			
		||||
				new Err(500, `Can't connect to db\n${err}`)
 | 
			
		||||
				return false
 | 
			
		||||
			})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (env.NORK.database.db.length > 0) {
 | 
			
		||||
		new Err(500, `unsupported database ${env.NORK.database.db}`)
 | 
			
		||||
		return false
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default connect
 | 
			
		||||
@@ -1,59 +0,0 @@
 | 
			
		||||
import path from 'path'
 | 
			
		||||
import fs from 'fs-extra'
 | 
			
		||||
import { Err } from '../services/globalService'
 | 
			
		||||
import dotenv from 'dotenv'
 | 
			
		||||
const env_path = process.env.NODE_ENV ? `../.env.${process.env.NODE_ENV}` : '../.env'
 | 
			
		||||
 | 
			
		||||
dotenv.config({ path: path.join(__dirname, env_path) })
 | 
			
		||||
const norkcfg = fs.readJSONSync(path.join(__dirname, '../../norkconfig.json'))
 | 
			
		||||
 | 
			
		||||
if (norkcfg.database) {
 | 
			
		||||
	if (norkcfg.database.db == 'postgresql') {
 | 
			
		||||
		if (!process.env.DB_PORT) {
 | 
			
		||||
			process.env.DB_PORT = '5432'
 | 
			
		||||
		}
 | 
			
		||||
		if (!process.env.DB_HOST) {
 | 
			
		||||
			process.env.DB_HOST = '127.0.0.1'
 | 
			
		||||
		}
 | 
			
		||||
		if (!process.env.DB_USERNAME || !process.env.DB_PASSWORD || !process.env.DB_DATABASE) {
 | 
			
		||||
			new Err(500, 'missing DB parameters in .env file')
 | 
			
		||||
			process.exit(1)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (!fs.existsSync(path.join(__dirname, env_path))) {
 | 
			
		||||
	console.log('$env_path = ', env_path)
 | 
			
		||||
	console.log('$__dirname = ', __dirname)
 | 
			
		||||
	new Err(500, `.env file for ${process.env.NODE_ENV ? process.env.NODE_ENV : ''} environment does not exists`)
 | 
			
		||||
	process.exit()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (process.env.JWT_SECRET === undefined || process.env.JWT_SECRET == '') {
 | 
			
		||||
	new Err(500, 'JWT_SECRET is not set!')
 | 
			
		||||
	process.exit()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default {
 | 
			
		||||
	// General
 | 
			
		||||
	APP_PORT: Number(process.env.APP_PORT),
 | 
			
		||||
	APP_HOST: String(process.env.APP_HOST),
 | 
			
		||||
	APP_HOSTNAME: process.env.APP_HOSTNAME !== undefined ? String(process.env.APP_HOSTNAME) : null,
 | 
			
		||||
	CORS_WHITELIST: String(process.env.CORS_WHITELIST),
 | 
			
		||||
	JWT_SECRET: String(process.env.JWT_SECRET),
 | 
			
		||||
	// MongoDB
 | 
			
		||||
	DB_URI: String(process.env.DB_URI),
 | 
			
		||||
	// PostgreSQL
 | 
			
		||||
	DB_PORT: Number(process.env.DB_PORT),
 | 
			
		||||
	DB_HOST: String(process.env.DB_HOST),
 | 
			
		||||
	DB_USERNAME: String(process.env.DB_USERNAME),
 | 
			
		||||
	DB_PASSWORD: String(process.env.DB_PASSWORD),
 | 
			
		||||
	DB_DATABASE: String(process.env.DB_DATABASE),
 | 
			
		||||
	// Nork
 | 
			
		||||
	NORK: norkcfg,
 | 
			
		||||
	// SMTP
 | 
			
		||||
	SMTP_HOST: String(process.env.SMTP_HOST),
 | 
			
		||||
	SMTP_USER: String(process.env.SMTP_USER),
 | 
			
		||||
	SMTP_PASS: String(process.env.SMTP_PASS),
 | 
			
		||||
	SMTP_FROM: String(process.env.SMTP_FROM)
 | 
			
		||||
}
 | 
			
		||||
@@ -1,10 +0,0 @@
 | 
			
		||||
import { Sequelize } from 'sequelize'
 | 
			
		||||
import env from './environment'
 | 
			
		||||
 | 
			
		||||
const db = new Sequelize(env.DB_DATABASE, env.DB_USERNAME, env.DB_PASSWORD, {
 | 
			
		||||
	host: env.DB_HOST,
 | 
			
		||||
	dialect: 'postgres',
 | 
			
		||||
	logging: false
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
export default db
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
import { Request, Response } from 'express'
 | 
			
		||||
 | 
			
		||||
export function root_get(req: Request, res: Response) {
 | 
			
		||||
	res.render('home')
 | 
			
		||||
	return true
 | 
			
		||||
}
 | 
			
		||||
@@ -1,4 +0,0 @@
 | 
			
		||||
export interface ErrType {
 | 
			
		||||
	code: number
 | 
			
		||||
	message: string
 | 
			
		||||
}
 | 
			
		||||
@@ -1,63 +0,0 @@
 | 
			
		||||
import { Request, Response, NextFunction } from 'express'
 | 
			
		||||
import jwt from 'jsonwebtoken'
 | 
			
		||||
import env from '../config/environment'
 | 
			
		||||
import { Err, Succ } from '../services/globalService'
 | 
			
		||||
import User from '../models/User' // uncomment this
 | 
			
		||||
 | 
			
		||||
export function requireAuth(req: Request, res: Response, next: NextFunction) {
 | 
			
		||||
	const token = req.cookies.jwt
 | 
			
		||||
	new Err(500, 'uncomment code in authMiddleware before using!')
 | 
			
		||||
	if (token) {
 | 
			
		||||
		jwt.verify(token, env.JWT_SECRET, async (err: any, decodedToken: any) => {
 | 
			
		||||
			if (err) {
 | 
			
		||||
				// console.error(err.message)
 | 
			
		||||
				res.status(401).json(new Err(401, 'user is not authenticated'))
 | 
			
		||||
			}
 | 
			
		||||
			if (!err) {
 | 
			
		||||
				const user = (async () => {
 | 
			
		||||
					if (env.NORK.db.orm) {
 | 
			
		||||
						if (env.NORK.db.orm == 'sequelize') {
 | 
			
		||||
							return await User.findByPk(decodedToken.id)
 | 
			
		||||
						}
 | 
			
		||||
						if (env.NORK.db.orm == 'mongoose') {
 | 
			
		||||
							return await User.findById(decodedToken.id)
 | 
			
		||||
						}
 | 
			
		||||
					} else {
 | 
			
		||||
						return null
 | 
			
		||||
					}
 | 
			
		||||
				})()
 | 
			
		||||
 | 
			
		||||
				if (user === null) {
 | 
			
		||||
					res.status(401).json(new Err(401, 'user is not authenticated'))
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				res.locals.user = user
 | 
			
		||||
				new Succ(100, 'user is authenticated')
 | 
			
		||||
				next()
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!token) {
 | 
			
		||||
		res.status(401).json(new Err(401, 'user is not authenticated'))
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function requireVerified(req: Request, res: Response, next: NextFunction) {
 | 
			
		||||
	if (res.locals.user._id) {
 | 
			
		||||
		if (res.locals.user.verified) {
 | 
			
		||||
			new Succ(100, 'user is verified')
 | 
			
		||||
			next()
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		res.status(403).json(new Err(403, 'user is not verified'))
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!res.locals.user._id) {
 | 
			
		||||
		res.status(401).json(new Err(401, 'user is not authenticated'))
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
import { Request, Response, NextFunction } from 'express'
 | 
			
		||||
import { validationResult } from 'express-validator'
 | 
			
		||||
import { Err } from '../services/globalService'
 | 
			
		||||
 | 
			
		||||
class Middleware {
 | 
			
		||||
	handleValidationError(req: Request, res: Response, next: NextFunction) {
 | 
			
		||||
		const error = validationResult(req)
 | 
			
		||||
		if (!error.isEmpty()) {
 | 
			
		||||
			new Err(400, error)
 | 
			
		||||
			return res.status(400).json(new Err(400, 'validation error', error.array()[0]))
 | 
			
		||||
		}
 | 
			
		||||
		next()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default new Middleware()
 | 
			
		||||
@@ -1,6 +0,0 @@
 | 
			
		||||
import { Router } from 'express'
 | 
			
		||||
import { router as sayHiMiddleware } from '../middlewares/sayHiMiddleware'
 | 
			
		||||
 | 
			
		||||
export const router = Router()
 | 
			
		||||
 | 
			
		||||
// router.use(sayHiMiddleware)
 | 
			
		||||
@@ -1,9 +0,0 @@
 | 
			
		||||
import { Router, Request, Response, NextFunction } from 'express'
 | 
			
		||||
 | 
			
		||||
export const router = Router()
 | 
			
		||||
 | 
			
		||||
router.use((req: Request, res: Response, next: NextFunction) => {
 | 
			
		||||
	console.log('Hi :)')
 | 
			
		||||
 | 
			
		||||
	next()
 | 
			
		||||
})
 | 
			
		||||
@@ -1,35 +0,0 @@
 | 
			
		||||
import { DataTypes, Model } from 'sequelize'
 | 
			
		||||
import path from 'path'
 | 
			
		||||
import db from '../config/sequelize.config.ts'
 | 
			
		||||
 | 
			
		||||
class Instance extends Model {}
 | 
			
		||||
 | 
			
		||||
Instance.init(
 | 
			
		||||
	{
 | 
			
		||||
		_id: {
 | 
			
		||||
			type: DataTypes.UUID,
 | 
			
		||||
			primaryKey: true,
 | 
			
		||||
			allowNull: false,
 | 
			
		||||
			unique: true,
 | 
			
		||||
		},
 | 
			
		||||
		username: {
 | 
			
		||||
			type: DataTypes.STRING,
 | 
			
		||||
			allowNull: false,
 | 
			
		||||
		},
 | 
			
		||||
		password: {
 | 
			
		||||
			type: DataTypes.STRING,
 | 
			
		||||
			allowNull: false,
 | 
			
		||||
		},
 | 
			
		||||
		email: {
 | 
			
		||||
			type: DataTypes.STRING,
 | 
			
		||||
			allowNull: false,
 | 
			
		||||
			unique: true,
 | 
			
		||||
		},
 | 
			
		||||
	},
 | 
			
		||||
	{
 | 
			
		||||
		sequelize: db,
 | 
			
		||||
		tableName: path.basename(__filename).split('.')[0].toLowerCase(),
 | 
			
		||||
	},
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
export default Instance
 | 
			
		||||
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 4.9 KiB  | 
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| 
		 Before Width: | Height: | Size: 5.8 KiB  | 
@@ -1,11 +0,0 @@
 | 
			
		||||
import { Request, Response, Router } from 'express'
 | 
			
		||||
import { router as rootRoutes } from './rootRoutes'
 | 
			
		||||
 | 
			
		||||
export const router = Router()
 | 
			
		||||
 | 
			
		||||
router.use(rootRoutes)
 | 
			
		||||
 | 
			
		||||
// 404
 | 
			
		||||
router.use((req: Request, res: Response) => {
 | 
			
		||||
	res.status(404).send('E404')
 | 
			
		||||
})
 | 
			
		||||
@@ -1,9 +0,0 @@
 | 
			
		||||
import { Router } from 'express'
 | 
			
		||||
import * as rootController from '../controllers/rootController'
 | 
			
		||||
import rootValidator from '../validators/rootValidator'
 | 
			
		||||
import handleValidation from '../middlewares/handleValidation'
 | 
			
		||||
 | 
			
		||||
export const router = Router()
 | 
			
		||||
const mws = [handleValidation.handleValidationError]
 | 
			
		||||
 | 
			
		||||
router.get('/', rootValidator.checkRootGet(), mws, rootController.root_get)
 | 
			
		||||
@@ -1,24 +0,0 @@
 | 
			
		||||
import http from 'http'
 | 
			
		||||
import { app } from './app'
 | 
			
		||||
import env from './config/environment'
 | 
			
		||||
import { Succ } from './services/globalService'
 | 
			
		||||
import database from './config/database'
 | 
			
		||||
const port: number = env.APP_PORT || 8080
 | 
			
		||||
const hostname: string = env.APP_HOSTNAME || 'localhost'
 | 
			
		||||
export const server = http.createServer(app)
 | 
			
		||||
 | 
			
		||||
// Server
 | 
			
		||||
export function runServer(): void {
 | 
			
		||||
	server.listen(port, hostname, () => {
 | 
			
		||||
		new Succ(200, `Server is listening on http://${hostname}:${port}`)
 | 
			
		||||
	})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
if (!env.NORK.database) {
 | 
			
		||||
	runServer()
 | 
			
		||||
} else {
 | 
			
		||||
	const db_connection = database()
 | 
			
		||||
	if (db_connection) {
 | 
			
		||||
		runServer()
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,173 +0,0 @@
 | 
			
		||||
import colors from 'colors'
 | 
			
		||||
import fs from 'fs'
 | 
			
		||||
import path from 'path'
 | 
			
		||||
 | 
			
		||||
export interface ErrType {
 | 
			
		||||
	code: number
 | 
			
		||||
	message: string
 | 
			
		||||
	data?: any
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class Err implements ErrType {
 | 
			
		||||
	code: number
 | 
			
		||||
	message: string
 | 
			
		||||
	data: any
 | 
			
		||||
 | 
			
		||||
	constructor(code: number, message: string | object, data: any = null) {
 | 
			
		||||
		this.code = code
 | 
			
		||||
		typeof message === 'object' ? (this.message = JSON.stringify(message)) : (this.message = message)
 | 
			
		||||
		data ? (this.data = data) : false
 | 
			
		||||
		// typeof data === 'object' ? (this.data = JSON.stringify(data)) : (this.data = data)
 | 
			
		||||
 | 
			
		||||
		this.drop()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	drop() {
 | 
			
		||||
		if (this.data) {
 | 
			
		||||
			console.log(colors.bgRed(`${this.code}`) + colors.bgBlack.red(` ${this.message}`) + this.data)
 | 
			
		||||
			Log.make('Err', this.code, this.message, this.data)
 | 
			
		||||
			return {
 | 
			
		||||
				code: this.code,
 | 
			
		||||
				message: this.message,
 | 
			
		||||
				data: this.data
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		console.log(colors.bgRed(`${this.code}`) + colors.bgBlack.red(` ${this.message}`))
 | 
			
		||||
		Log.make('Err', this.code, this.message)
 | 
			
		||||
		return {
 | 
			
		||||
			code: this.code,
 | 
			
		||||
			message: this.message
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class Succ {
 | 
			
		||||
	code: number
 | 
			
		||||
	message: string
 | 
			
		||||
	data?: any
 | 
			
		||||
 | 
			
		||||
	constructor(code: number, message: string, data: any = null) {
 | 
			
		||||
		this.code = code
 | 
			
		||||
		this.message = message
 | 
			
		||||
		data ? (this.data = data) : false
 | 
			
		||||
		this.drop()
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	drop() {
 | 
			
		||||
		if (this.data) {
 | 
			
		||||
			console.log(colors.bgGreen.black(`${this.code}`) + colors.green.bgBlack(` ${this.message}`) + this.data)
 | 
			
		||||
			return {
 | 
			
		||||
				code: this.code,
 | 
			
		||||
				message: this.message,
 | 
			
		||||
				data: this.data
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		console.log(colors.bgGreen.black(`${this.code}`) + colors.green.bgBlack(` ${this.message}`))
 | 
			
		||||
		return {
 | 
			
		||||
			code: this.code,
 | 
			
		||||
			message: this.message
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface LogType {
 | 
			
		||||
	type: 'Err' | 'Succ' | 'Info'
 | 
			
		||||
	code?: number
 | 
			
		||||
	message?: string
 | 
			
		||||
	data?: any
 | 
			
		||||
	logFile?: string
 | 
			
		||||
}
 | 
			
		||||
export class Log implements LogType {
 | 
			
		||||
	type: 'Err' | 'Succ' | 'Info'
 | 
			
		||||
	code?: number
 | 
			
		||||
	message?: string
 | 
			
		||||
	data?: any
 | 
			
		||||
	logFile?: string
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * @param type
 | 
			
		||||
	 *  - Type of log
 | 
			
		||||
	 *  - Err | Succ | Info
 | 
			
		||||
	 * @param code
 | 
			
		||||
	 *  - not required
 | 
			
		||||
	 *  - HTTP status code
 | 
			
		||||
	 * @param message
 | 
			
		||||
	 *  - could be anything
 | 
			
		||||
	 * @param data
 | 
			
		||||
	 *  - could be anything
 | 
			
		||||
	 * @param logFile
 | 
			
		||||
	 *  - name of logFile
 | 
			
		||||
	 *  - default is log type file
 | 
			
		||||
	 */
 | 
			
		||||
	constructor(type: 'Err' | 'Succ' | 'Info', code?: number, message?: string, data?: any, logFile?: string) {
 | 
			
		||||
		this.type = type
 | 
			
		||||
		this.code = code
 | 
			
		||||
		this.message = message
 | 
			
		||||
		this.data = data
 | 
			
		||||
		this.logFile = logFile
 | 
			
		||||
 | 
			
		||||
		if (!this.logFile) {
 | 
			
		||||
			this.logFile = `${type}.global.log`
 | 
			
		||||
		} else {
 | 
			
		||||
			this.logFile = this.logFile + '.log'
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		this.logFile = path.join(__dirname, this.logFile)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static pathMake(type: string, name?: string) {
 | 
			
		||||
		let logName
 | 
			
		||||
		if (!name) {
 | 
			
		||||
			logName = `${type}.global.log`
 | 
			
		||||
		} else {
 | 
			
		||||
			logName = name + '.log'
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return path.join(__dirname, '../logs/' + logName)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * returns current date in my custom format
 | 
			
		||||
	 */
 | 
			
		||||
	static dateNow(): string {
 | 
			
		||||
		/**
 | 
			
		||||
		 * @param num: number
 | 
			
		||||
		 *
 | 
			
		||||
		 * receives number and returns two digits number
 | 
			
		||||
		 * example:
 | 
			
		||||
		 *   input num = 9 => returns string 09
 | 
			
		||||
		 */
 | 
			
		||||
		function add0(num: number): string {
 | 
			
		||||
			if (num.toString().length <= 1) {
 | 
			
		||||
				return '0' + String(num)
 | 
			
		||||
			}
 | 
			
		||||
			return String(num)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		const d = new Date()
 | 
			
		||||
		return `${d.getFullYear()}-${add0(d.getMonth() + 1)}-${add0(d.getDate())} ${add0(d.getHours())}:${add0(d.getMinutes())}:${add0(d.getSeconds())}`
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	static make(type: 'Err' | 'Succ' | 'Info', code?: number, message?: string, data?: any, logFile?: string) {
 | 
			
		||||
		let realPath = Log.pathMake(type, logFile)
 | 
			
		||||
		let formattedData = `Date: "${Log.dateNow()}" Type: "${type}"`
 | 
			
		||||
 | 
			
		||||
		code ? (formattedData += ` Code: "${code}"`) : false
 | 
			
		||||
		message ? (formattedData += ` Message: "${message}"`) : false
 | 
			
		||||
		if (data) {
 | 
			
		||||
			if (typeof data === 'object') {
 | 
			
		||||
				data = JSON.stringify(data)
 | 
			
		||||
			}
 | 
			
		||||
			formattedData += ` Data: "${data}"`
 | 
			
		||||
		}
 | 
			
		||||
		formattedData += '\n'
 | 
			
		||||
 | 
			
		||||
		if (fs.existsSync(realPath)) {
 | 
			
		||||
			fs.appendFileSync(realPath, formattedData)
 | 
			
		||||
		} else {
 | 
			
		||||
			fs.writeFileSync(realPath, formattedData)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,3 +0,0 @@
 | 
			
		||||
export const helloWorld = () => {
 | 
			
		||||
	console.log('hello world')
 | 
			
		||||
}
 | 
			
		||||
@@ -1,7 +0,0 @@
 | 
			
		||||
import * as shell from 'shelljs'
 | 
			
		||||
 | 
			
		||||
// Copy all the view templates
 | 
			
		||||
shell.cp('-R', 'src/views', 'dist/')
 | 
			
		||||
shell.cp('-R', 'src/public', 'dist/')
 | 
			
		||||
shell.cp('-R', 'src/models', 'dist/')
 | 
			
		||||
shell.cp('-u', 'src/.env', 'dist/')
 | 
			
		||||
@@ -1,9 +0,0 @@
 | 
			
		||||
import { body, param, query } from 'express-validator'
 | 
			
		||||
 | 
			
		||||
class rootValidator {
 | 
			
		||||
	checkRootGet() {
 | 
			
		||||
		return []
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default new rootValidator()
 | 
			
		||||
@@ -1,69 +0,0 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html lang="en">
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
    <title>New Project</title>
 | 
			
		||||
    <link rel="preconnect" href="https://fonts.googleapis.com">
 | 
			
		||||
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
 | 
			
		||||
    <link href="https://fonts.googleapis.com/css2?family=Open+Sans&display=swap" rel="stylesheet">
 | 
			
		||||
    <style>
 | 
			
		||||
        * {
 | 
			
		||||
            box-sizing: border-box;
 | 
			
		||||
            margin: 0;
 | 
			
		||||
            padding: 0;
 | 
			
		||||
        }
 | 
			
		||||
        body {
 | 
			
		||||
            font-family: 'Open Sans', sans-serif;
 | 
			
		||||
        }
 | 
			
		||||
        .content {
 | 
			
		||||
            width: 100vw;
 | 
			
		||||
            height: 100vh;
 | 
			
		||||
            display: flex;
 | 
			
		||||
            justify-content: space-between;
 | 
			
		||||
            padding-top: 5rem;
 | 
			
		||||
            flex-direction: column;
 | 
			
		||||
        }
 | 
			
		||||
        footer, .welcome {
 | 
			
		||||
            display: flex;
 | 
			
		||||
            justify-content: center;
 | 
			
		||||
        }
 | 
			
		||||
        .welcome {
 | 
			
		||||
            display: flex;
 | 
			
		||||
            justify-content: center;
 | 
			
		||||
            align-items: center;
 | 
			
		||||
            flex-direction: column;
 | 
			
		||||
        }
 | 
			
		||||
        img {
 | 
			
		||||
            width: 200px;
 | 
			
		||||
            padding-top: 2rem;
 | 
			
		||||
        }
 | 
			
		||||
        footer {
 | 
			
		||||
            padding-bottom: 2rem;
 | 
			
		||||
            text-align: center;
 | 
			
		||||
        }
 | 
			
		||||
        .logos {
 | 
			
		||||
            display: flex;
 | 
			
		||||
            align-items: center;
 | 
			
		||||
            gap: 1rem;
 | 
			
		||||
        }
 | 
			
		||||
    </style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
    <div class="content">
 | 
			
		||||
        <div class="welcome">
 | 
			
		||||
            <h1>Let's make something amazing!</h1>
 | 
			
		||||
            <div class="logos">
 | 
			
		||||
                <img src="/nodejs_logo.svg" alt="node.js logo">
 | 
			
		||||
                <img src="/expressjs.png" alt="express.js logo">
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <footer>
 | 
			
		||||
            <div class="author">
 | 
			
		||||
                <p>Made by </p><a href="http://www.filiprojek.cz">filiprojek.cz</a>
 | 
			
		||||
            </div>
 | 
			
		||||
        </footer>
 | 
			
		||||
    </div>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -1,63 +0,0 @@
 | 
			
		||||
{
 | 
			
		||||
	"compilerOptions": {
 | 
			
		||||
		/* Visit https://aka.ms/tsconfig.json to read more about this file */
 | 
			
		||||
 | 
			
		||||
		/* Basic Options */
 | 
			
		||||
		// "incremental": true,                         /* Enable incremental compilation */
 | 
			
		||||
		"target": "es6",
 | 
			
		||||
    
 | 
			
		||||
		/* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
 | 
			
		||||
		"module": "commonjs",
 | 
			
		||||
 | 
			
		||||
		/* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
 | 
			
		||||
		// "lib": [],                                   /* Specify library files to be included in the compilation. */
 | 
			
		||||
		// "allowJs": true,                             /* Allow javascript files to be compiled. */
 | 
			
		||||
		// "checkJs": true,                             /* Report errors in .js files. */
 | 
			
		||||
		// "jsx": "preserve",                           /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */
 | 
			
		||||
		// "declaration": true,                         /* Generates corresponding '.d.ts' file. */
 | 
			
		||||
		// "declarationMap": true,                      /* Generates a sourcemap for each corresponding '.d.ts' file. */
 | 
			
		||||
		// "sourceMap": true,                           /* Generates corresponding '.map' file. */
 | 
			
		||||
		// "outFile": "./",                             /* Concatenate and emit output to single file. */
 | 
			
		||||
		"outDir": "./dist",
 | 
			
		||||
 | 
			
		||||
		/* Redirect output structure to the directory. */
 | 
			
		||||
		"rootDir": "./src",
 | 
			
		||||
		/* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
 | 
			
		||||
		// "composite": true,                           /* Enable project compilation */
 | 
			
		||||
		// "tsBuildInfoFile": "./",                     /* Specify file to store incremental compilation information */
 | 
			
		||||
		// "removeComments": true,                      /* Do not emit comments to output. */
 | 
			
		||||
		// "noEmit": true,                              /* Do not emit outputs. */
 | 
			
		||||
		// "importHelpers": true,                       /* Import emit helpers from 'tslib'. */
 | 
			
		||||
		// "downlevelIteration": true,                  /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
 | 
			
		||||
		// "isolatedModules": true,                     /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
 | 
			
		||||
 | 
			
		||||
		/* Strict Type-Checking Options */
 | 
			
		||||
		"strict": true,
 | 
			
		||||
		/* Enable all strict type-checking options. */
 | 
			
		||||
		// "noImplicitAny": true,                       /* Raise error on expressions and declarations with an implied 'any' type. */
 | 
			
		||||
		// "strictNullChecks": true,                    /* Enable strict null checks. */
 | 
			
		||||
		// "strictFunctionTypes": true,                 /* Enable strict checking of function types. */
 | 
			
		||||
		// "strictBindCallApply": true,                 /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
 | 
			
		||||
		// "strictPropertyInitialization": true,        /* Enable strict checking of property initialization in classes. */
 | 
			
		||||
		// "noImplicitThis": true,                      /* Raise error on 'this' expressions with an implied 'any' type. */
 | 
			
		||||
		// "alwaysStrict": true,                        /* Parse in strict mode and emit "use strict" for each source file. */
 | 
			
		||||
 | 
			
		||||
		"baseUrl": "./",
 | 
			
		||||
		"esModuleInterop": true,
 | 
			
		||||
		/* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
 | 
			
		||||
		"resolveJsonModule": true,
 | 
			
		||||
		// "preserveSymlinks": true,                    /* Do not resolve the real path of symlinks. */
 | 
			
		||||
		// "allowUmdGlobalAccess": true,                /* Allow accessing UMD globals from modules. */
 | 
			
		||||
		/* Experimental Options */
 | 
			
		||||
		"experimentalDecorators": true,
 | 
			
		||||
		/* Enables experimental support for ES7 decorators. */
 | 
			
		||||
		"emitDecoratorMetadata": true,
 | 
			
		||||
		/* Enables experimental support for emitting type metadata for decorators. */
 | 
			
		||||
		/* Advanced Options */
 | 
			
		||||
		"skipLibCheck": true,
 | 
			
		||||
		/* Skip type checking of declaration files. */
 | 
			
		||||
		"forceConsistentCasingInFileNames": true
 | 
			
		||||
		/* Disallow inconsistently-cased references to the same file. */
 | 
			
		||||
	},
 | 
			
		||||
	"exclude": ["src/tests"]
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user