mirror of
				https://github.com/aurora-dot/pastel.codes.git
				synced 2025-11-04 09:01:34 +00:00 
			
		
		
		
	Compare commits
	
		
			2 Commits
		
	
	
		
			4b6ff6616f
			...
			snyk-fix-8
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					7ff9f6f361 | ||
| 8449b30401 | 
							
								
								
									
										15
									
								
								.editorconfig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								.editorconfig
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					# EditorConfig is awesome: https://EditorConfig.org
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# top-most EditorConfig file
 | 
				
			||||||
 | 
					root = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[*]
 | 
				
			||||||
 | 
					indent_style = space
 | 
				
			||||||
 | 
					indent_size = 2
 | 
				
			||||||
 | 
					end_of_line = lf
 | 
				
			||||||
 | 
					charset = utf-8
 | 
				
			||||||
 | 
					trim_trailing_whitespace = false
 | 
				
			||||||
 | 
					insert_final_newline = false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[pug.ts]
 | 
				
			||||||
 | 
					indent_size = 4
 | 
				
			||||||
							
								
								
									
										3
									
								
								.eslintrc.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								.eslintrc.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "extends": ["prettier"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										1
									
								
								.husky/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.husky/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					_
 | 
				
			||||||
							
								
								
									
										4
									
								
								.husky/pre-commit
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										4
									
								
								.husky/pre-commit
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,4 @@
 | 
				
			|||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					. "$(dirname "$0")/_/husky.sh"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					npx lint-staged
 | 
				
			||||||
							
								
								
									
										8
									
								
								.prettierrc.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								.prettierrc.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "trailingComma": "es5",
 | 
				
			||||||
 | 
					  "semi": true,
 | 
				
			||||||
 | 
					  "tabWidth": 2,
 | 
				
			||||||
 | 
					  "singleQuote": true,
 | 
				
			||||||
 | 
					  "jsxSingleQuote": true,
 | 
				
			||||||
 | 
					  "plugins": ["prettier-plugin-tailwindcss"]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										70
									
								
								app.js
									
									
									
									
									
								
							
							
						
						
									
										70
									
								
								app.js
									
									
									
									
									
								
							@@ -4,7 +4,7 @@ var path = require('path');
 | 
				
			|||||||
var cookieParser = require('cookie-parser');
 | 
					var cookieParser = require('cookie-parser');
 | 
				
			||||||
var mLogger = require('morgan');
 | 
					var mLogger = require('morgan');
 | 
				
			||||||
var logger = require('./config/winston');
 | 
					var logger = require('./config/winston');
 | 
				
			||||||
const helmet = require("helmet");
 | 
					const helmet = require('helmet');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var indexRouter = require('./routes/index');
 | 
					var indexRouter = require('./routes/index');
 | 
				
			||||||
var aboutRouter = require('./routes/about');
 | 
					var aboutRouter = require('./routes/about');
 | 
				
			||||||
@@ -12,7 +12,8 @@ var contactRouter = require('./routes/contact');
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var app = express();
 | 
					var app = express();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (process.env.IS_DOCKER != 'true') app.set('trust proxy', 'loopback,uniquelocal');
 | 
					if (process.env.IS_DOCKER != 'true')
 | 
				
			||||||
 | 
					  app.set('trust proxy', 'loopback,uniquelocal');
 | 
				
			||||||
app.disable('x-powered-by');
 | 
					app.disable('x-powered-by');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// view engine setup
 | 
					// view engine setup
 | 
				
			||||||
@@ -20,26 +21,43 @@ app.set('views', path.join(__dirname, 'views'));
 | 
				
			|||||||
app.set('view engine', 'pug');
 | 
					app.set('view engine', 'pug');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if (process.env.NODE_ENV === 'production') {
 | 
					if (process.env.NODE_ENV === 'production') {
 | 
				
			||||||
    app.use(mLogger("common", { "stream": logger.stream }));
 | 
					  app.use(mLogger('common', { stream: logger.stream }));
 | 
				
			||||||
} else {
 | 
					} else {
 | 
				
			||||||
    app.use(mLogger('dev'));
 | 
					  app.use(mLogger('dev'));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.use(helmet());
 | 
					app.use(helmet());
 | 
				
			||||||
app.use(
 | 
					app.use(
 | 
				
			||||||
    helmet.contentSecurityPolicy({
 | 
					  helmet.contentSecurityPolicy({
 | 
				
			||||||
      directives: {
 | 
					    directives: {
 | 
				
			||||||
        defaultSrc: ["'self'"],
 | 
					      defaultSrc: ["'self'"],
 | 
				
			||||||
        scriptSrc: ["'self'", "'unsafe-inline'", "'unsafe-eval'", "https://hcaptcha.com", "https://*.hcaptcha.com", "https://cdn.ravenjs.com/"],
 | 
					      scriptSrc: [
 | 
				
			||||||
        imgSrc: ["'self'", "https://blog.pastel.codes", "https://static.ghost.org", "https://secure.gravatar.com"],
 | 
					        "'self'",
 | 
				
			||||||
        styleSrc: ["'self'", "'unsafe-inline'", "https://hcaptcha.com", "https://*.hcaptcha.com"],
 | 
					        "'unsafe-inline'",
 | 
				
			||||||
        fontSrc: ["'self'", "data:"],
 | 
					        "'unsafe-eval'",
 | 
				
			||||||
        frameSrc: ["https://hcaptcha.com", "https://*.hcaptcha.com"],
 | 
					        'https://hcaptcha.com',
 | 
				
			||||||
        objectSrc: ["'none'"],
 | 
					        'https://*.hcaptcha.com',
 | 
				
			||||||
        upgradeInsecureRequests: [],
 | 
					        'https://cdn.ravenjs.com/',
 | 
				
			||||||
      },
 | 
					      ],
 | 
				
			||||||
    })
 | 
					      imgSrc: [
 | 
				
			||||||
  );
 | 
					        "'self'",
 | 
				
			||||||
 | 
					        'https://blog.pastel.codes',
 | 
				
			||||||
 | 
					        'https://static.ghost.org',
 | 
				
			||||||
 | 
					        'https://secure.gravatar.com',
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      styleSrc: [
 | 
				
			||||||
 | 
					        "'self'",
 | 
				
			||||||
 | 
					        "'unsafe-inline'",
 | 
				
			||||||
 | 
					        'https://hcaptcha.com',
 | 
				
			||||||
 | 
					        'https://*.hcaptcha.com',
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					      fontSrc: ["'self'", 'data:'],
 | 
				
			||||||
 | 
					      frameSrc: ['https://hcaptcha.com', 'https://*.hcaptcha.com'],
 | 
				
			||||||
 | 
					      objectSrc: ["'none'"],
 | 
				
			||||||
 | 
					      upgradeInsecureRequests: [],
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app.use(express.json());
 | 
					app.use(express.json());
 | 
				
			||||||
app.use(express.urlencoded({ extended: false }));
 | 
					app.use(express.urlencoded({ extended: false }));
 | 
				
			||||||
@@ -51,19 +69,19 @@ app.use('/about', aboutRouter);
 | 
				
			|||||||
app.use('/contact', contactRouter);
 | 
					app.use('/contact', contactRouter);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// catch 404 and forward to error handler
 | 
					// catch 404 and forward to error handler
 | 
				
			||||||
app.use(function(req, res, next) {
 | 
					app.use(function (req, res, next) {
 | 
				
			||||||
    next(createError(404));
 | 
					  next(createError(404));
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// error handler
 | 
					// error handler
 | 
				
			||||||
app.use(function(err, req, res, next) {
 | 
					app.use(function (err, req, res, _next) {
 | 
				
			||||||
    // set locals, only providing error in development
 | 
					  // set locals, only providing error in development
 | 
				
			||||||
    res.locals.message = err.message;
 | 
					  res.locals.message = err.message;
 | 
				
			||||||
    res.locals.error = req.app.get('env') === 'development' ? err : {};
 | 
					  res.locals.error = req.app.get('env') === 'development' ? err : {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // render the error page
 | 
					  // render the error page
 | 
				
			||||||
    res.status(err.status || 500);
 | 
					  res.status(err.status || 500);
 | 
				
			||||||
    res.render('error', { title: 'Error', description: "Error" });
 | 
					  res.render('error', { title: 'Error', description: 'Error' });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = app;
 | 
					module.exports = app;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										64
									
								
								bin/www
									
									
									
									
									
								
							
							
						
						
									
										64
									
								
								bin/www
									
									
									
									
									
								
							@@ -35,19 +35,19 @@ server.on('listening', onListening);
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function normalizePort(val) {
 | 
					function normalizePort(val) {
 | 
				
			||||||
    var port = parseInt(val, 10);
 | 
					  var port = parseInt(val, 10);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (isNaN(port)) {
 | 
					  if (isNaN(port)) {
 | 
				
			||||||
        // named pipe
 | 
					    // named pipe
 | 
				
			||||||
        return val;
 | 
					    return val;
 | 
				
			||||||
    }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (port >= 0) {
 | 
					  if (port >= 0) {
 | 
				
			||||||
        // port number
 | 
					    // port number
 | 
				
			||||||
        return port;
 | 
					    return port;
 | 
				
			||||||
    }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return false;
 | 
					  return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -55,27 +55,25 @@ function normalizePort(val) {
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function onError(error) {
 | 
					function onError(error) {
 | 
				
			||||||
    if (error.syscall !== 'listen') {
 | 
					  if (error.syscall !== 'listen') {
 | 
				
			||||||
        throw error;
 | 
					    throw error;
 | 
				
			||||||
    }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var bind = typeof port === 'string'
 | 
					  var bind = typeof port === 'string' ? 'Pipe ' + port : 'Port ' + port;
 | 
				
			||||||
        ? 'Pipe ' + port
 | 
					 | 
				
			||||||
        : 'Port ' + port;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // handle specific listen errors with friendly messages
 | 
					  // handle specific listen errors with friendly messages
 | 
				
			||||||
    switch (error.code) {
 | 
					  switch (error.code) {
 | 
				
			||||||
        case 'EACCES':
 | 
					    case 'EACCES':
 | 
				
			||||||
            console.error(bind + ' requires elevated privileges');
 | 
					      console.error(bind + ' requires elevated privileges');
 | 
				
			||||||
            process.exit(1);
 | 
					      process.exit(1);
 | 
				
			||||||
            break;
 | 
					      break;
 | 
				
			||||||
        case 'EADDRINUSE':
 | 
					    case 'EADDRINUSE':
 | 
				
			||||||
            console.error(bind + ' is already in use');
 | 
					      console.error(bind + ' is already in use');
 | 
				
			||||||
            process.exit(1);
 | 
					      process.exit(1);
 | 
				
			||||||
            break;
 | 
					      break;
 | 
				
			||||||
        default:
 | 
					    default:
 | 
				
			||||||
            throw error;
 | 
					      throw error;
 | 
				
			||||||
    }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -83,9 +81,7 @@ function onError(error) {
 | 
				
			|||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function onListening() {
 | 
					function onListening() {
 | 
				
			||||||
    var addr = server.address();
 | 
					  var addr = server.address();
 | 
				
			||||||
    var bind = typeof addr === 'string'
 | 
					  var bind = typeof addr === 'string' ? 'pipe ' + addr : 'port ' + addr.port;
 | 
				
			||||||
        ? 'pipe ' + addr
 | 
					  debug('Listening on ' + bind);
 | 
				
			||||||
        : 'port ' + addr.port;
 | 
					 | 
				
			||||||
    debug('Listening on ' + bind);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,29 +2,29 @@ var winston = require('winston');
 | 
				
			|||||||
var appRoot = require('app-root-path');
 | 
					var appRoot = require('app-root-path');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var logger = new winston.createLogger({
 | 
					var logger = new winston.createLogger({
 | 
				
			||||||
    transports: [
 | 
					  transports: [
 | 
				
			||||||
        new winston.transports.File({
 | 
					    new winston.transports.File({
 | 
				
			||||||
            level: 'info',
 | 
					      level: 'info',
 | 
				
			||||||
            filename: `${appRoot}/logs/app.log`,
 | 
					      filename: `${appRoot}/logs/app.log`,
 | 
				
			||||||
            handleExceptions: true,
 | 
					      handleExceptions: true,
 | 
				
			||||||
            json: true,
 | 
					      json: true,
 | 
				
			||||||
            maxsize: 5242880, //5MB
 | 
					      maxsize: 5242880, //5MB
 | 
				
			||||||
            maxFiles: 5,
 | 
					      maxFiles: 5,
 | 
				
			||||||
            colorize: false
 | 
					      colorize: false,
 | 
				
			||||||
        }),
 | 
					    }),
 | 
				
			||||||
        new winston.transports.Console({
 | 
					    new winston.transports.Console({
 | 
				
			||||||
            level: 'debug',
 | 
					      level: 'debug',
 | 
				
			||||||
            handleExceptions: true,
 | 
					      handleExceptions: true,
 | 
				
			||||||
            json: false,
 | 
					      json: false,
 | 
				
			||||||
            colorize: true
 | 
					      colorize: true,
 | 
				
			||||||
        })
 | 
					    }),
 | 
				
			||||||
    ],
 | 
					  ],
 | 
				
			||||||
    exitOnError: false
 | 
					  exitOnError: false,
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
logger.stream = {
 | 
					logger.stream = {
 | 
				
			||||||
    write: function(message, encoding){
 | 
					  write: function (message, _encoding) {
 | 
				
			||||||
        logger.info(message);
 | 
					    logger.info(message);
 | 
				
			||||||
    }
 | 
					  },
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
module.exports = logger
 | 
					module.exports = logger;
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										20
									
								
								eslint.config.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								eslint.config.mjs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					import globals from 'globals';
 | 
				
			||||||
 | 
					import pluginJs from '@eslint/js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default [
 | 
				
			||||||
 | 
					  { files: ['**/*.js'], languageOptions: { sourceType: 'commonjs' } },
 | 
				
			||||||
 | 
					  { languageOptions: { globals: { ...globals.browser, ...globals.node } } },
 | 
				
			||||||
 | 
					  pluginJs.configs.recommended,
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    rules: {
 | 
				
			||||||
 | 
					      'no-unused-vars': [
 | 
				
			||||||
 | 
					        'error',
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          argsIgnorePattern: '^_',
 | 
				
			||||||
 | 
					          varsIgnorePattern: '^_',
 | 
				
			||||||
 | 
					          caughtErrorsIgnorePattern: '^_',
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					      ],
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					];
 | 
				
			||||||
							
								
								
									
										5221
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5221
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										36
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								package.json
									
									
									
									
									
								
							@@ -12,14 +12,19 @@
 | 
				
			|||||||
  },
 | 
					  },
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
    "test": "echo \"Error: no test specified\" && exit 1",
 | 
					    "test": "echo \"Error: no test specified\" && exit 1",
 | 
				
			||||||
    "start": "npx nodemon ./bin/www -e js,pug,sass",
 | 
					    "dev": "npx nodemon ./bin/www -e js,pug,sass",
 | 
				
			||||||
 | 
					    "start": "npx ./bin/www -e js,pug,sass",
 | 
				
			||||||
    "watch-tailwind": "npx npm-watch",
 | 
					    "watch-tailwind": "npx npm-watch",
 | 
				
			||||||
    "build-tailwind": "npx postcss src/tailwind.css -o public/stylesheets/style.css"
 | 
					    "build-tailwind": "npx postcss src/tailwind.css -o public/stylesheets/style.css",
 | 
				
			||||||
 | 
					    "lint": "prettier --check . && eslint .",
 | 
				
			||||||
 | 
					    "format": "prettier --write --ignore-path .gitignore .",
 | 
				
			||||||
 | 
					    "prepare": "husky install"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "@sendgrid/mail": "^7.4.4",
 | 
					    "@sendgrid/mail": "^8.1.3",
 | 
				
			||||||
    "app-root-path": "^3.0.0",
 | 
					    "app-root-path": "^3.0.0",
 | 
				
			||||||
    "axios": "^0.21.3",
 | 
					    "autoprefixer": "^10.3.4",
 | 
				
			||||||
 | 
					    "axios": "^1.6.8",
 | 
				
			||||||
    "cookie-parser": "^1.4.5",
 | 
					    "cookie-parser": "^1.4.5",
 | 
				
			||||||
    "express": "^4.17.1",
 | 
					    "express": "^4.17.1",
 | 
				
			||||||
    "express-rate-limit": "^5.2.6",
 | 
					    "express-rate-limit": "^5.2.6",
 | 
				
			||||||
@@ -28,12 +33,25 @@
 | 
				
			|||||||
    "http-errors": "^1.8.0",
 | 
					    "http-errors": "^1.8.0",
 | 
				
			||||||
    "morgan": "^1.10.0",
 | 
					    "morgan": "^1.10.0",
 | 
				
			||||||
    "nodemailer": "^6.6.1",
 | 
					    "nodemailer": "^6.6.1",
 | 
				
			||||||
 | 
					    "npm-watch": "^0.12.0",
 | 
				
			||||||
 | 
					    "postcss-cli": "^8.3.1",
 | 
				
			||||||
    "pug": "^3.0.2",
 | 
					    "pug": "^3.0.2",
 | 
				
			||||||
    "tailwind-hamburgers": "^1.1.1",
 | 
					    "tailwind-hamburgers": "^1.1.1",
 | 
				
			||||||
    "winston": "^3.3.3",
 | 
					    "tailwindcss": "^2.2.15",
 | 
				
			||||||
    "autoprefixer": "^10.3.4",
 | 
					    "winston": "^3.3.3"
 | 
				
			||||||
    "npm-watch": "^0.11.0",
 | 
					  },
 | 
				
			||||||
    "postcss-cli": "^8.3.1",
 | 
					  "devDependencies": {
 | 
				
			||||||
    "tailwindcss": "^2.2.15"
 | 
					    "@eslint/js": "^9.1.1",
 | 
				
			||||||
 | 
					    "eslint": "^9.1.1",
 | 
				
			||||||
 | 
					    "eslint-config-prettier": "^9.1.0",
 | 
				
			||||||
 | 
					    "globals": "^15.1.0",
 | 
				
			||||||
 | 
					    "husky": "^9.0.11",
 | 
				
			||||||
 | 
					    "lint-staged": "^15.2.2",
 | 
				
			||||||
 | 
					    "prettier": "^3.2.5",
 | 
				
			||||||
 | 
					    "prettier-plugin-tailwindcss": "^0.5.14"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "lint-staged": {
 | 
				
			||||||
 | 
					    "*.js": "eslint --cache --fix",
 | 
				
			||||||
 | 
					    "*.{js,css,md,pug}": "prettier --write"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,3 @@
 | 
				
			|||||||
module.exports = {
 | 
					module.exports = {
 | 
				
			||||||
    plugins: [
 | 
					  plugins: [require('tailwindcss'), require('autoprefixer')],
 | 
				
			||||||
        require('tailwindcss'),
 | 
					};
 | 
				
			||||||
        require('autoprefixer')
 | 
					 | 
				
			||||||
    ]
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,293 +3,289 @@ $black: #002234
 | 
				
			|||||||
$green: #CDE7B0
 | 
					$green: #CDE7B0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@font-face
 | 
					@font-face
 | 
				
			||||||
    font-family: 'Titling Gothic FB'
 | 
					  font-family: 'Titling Gothic FB'
 | 
				
			||||||
    src: url("../fonts/TITLINGGOTHICFB-WIDE.OTF") format('opentype')
 | 
					  src: url("../fonts/TITLINGGOTHICFB-WIDE.OTF") format('opentype')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@font-face
 | 
					@font-face
 | 
				
			||||||
    font-family: 'Gilroy'
 | 
					  font-family: 'Gilroy'
 | 
				
			||||||
    src: url("../fonts/Gilroy-ExtraBold.otf") format('opentype')
 | 
					  src: url("../fonts/Gilroy-ExtraBold.otf") format('opentype')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@font-face
 | 
					@font-face
 | 
				
			||||||
    font-family: 'Apercu Mono'
 | 
					  font-family: 'Apercu Mono'
 | 
				
			||||||
    src: url("../fonts/ApercuMono.ttf") format('truetype')
 | 
					  src: url("../fonts/ApercuMono.ttf") format('truetype')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
html, body
 | 
					html, body
 | 
				
			||||||
    width: 100%
 | 
					  width: 100%
 | 
				
			||||||
    height: 100%
 | 
					  height: 100%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
body
 | 
					body
 | 
				
			||||||
    background-color: $black
 | 
					  background-color: $black
 | 
				
			||||||
    color: $pink
 | 
					  color: $pink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
h1
 | 
					h1
 | 
				
			||||||
    font-family: "Gilroy", sans-serif
 | 
					  font-family: "Gilroy", sans-serif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
h2
 | 
					h2
 | 
				
			||||||
    font-weight: bold
 | 
					  font-weight: bold
 | 
				
			||||||
    font-family: "Apercu Mono", monospace
 | 
					  font-family: "Apercu Mono", monospace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
p, label, input, textarea
 | 
					p, label, input, textarea
 | 
				
			||||||
    font-family: "Apercu Mono", monospace
 | 
					  font-family: "Apercu Mono", monospace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
label
 | 
					label
 | 
				
			||||||
    font-size: 3vh
 | 
					  font-size: 3vh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
a:hover
 | 
					a:hover
 | 
				
			||||||
    color: $green
 | 
					  color: $green
 | 
				
			||||||
 | 
					
 | 
				
			||||||
article
 | 
					article
 | 
				
			||||||
    min-height: 100%
 | 
					  min-height: 100%
 | 
				
			||||||
    display: grid
 | 
					  display: grid
 | 
				
			||||||
    grid-template-rows: auto 1fr auto
 | 
					  grid-template-rows: auto 1fr auto
 | 
				
			||||||
    grid-template-columns: 100%
 | 
					  grid-template-columns: 100%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
header
 | 
					header
 | 
				
			||||||
    nav
 | 
					  nav
 | 
				
			||||||
        a
 | 
					    a
 | 
				
			||||||
            span
 | 
					      span
 | 
				
			||||||
                font-size: 2rem
 | 
					        font-size: 2rem
 | 
				
			||||||
                font-family: 'Titling Gothic FB', sans-serif
 | 
					        font-family: 'Titling Gothic FB', sans-serif
 | 
				
			||||||
                color: $pink
 | 
					        color: $pink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        #navbarSupportedContent23
 | 
					        #navbarSupportedContent23
 | 
				
			||||||
            ul
 | 
					          ul
 | 
				
			||||||
                background-color: $pink
 | 
					            background-color: $pink
 | 
				
			||||||
                li
 | 
					            li
 | 
				
			||||||
                    transition: 0.5s
 | 
					              transition: 0.5s
 | 
				
			||||||
                    background-color: $pink
 | 
					              background-color: $pink
 | 
				
			||||||
                    text-align: center
 | 
					              text-align: center
 | 
				
			||||||
                    a
 | 
					              a
 | 
				
			||||||
                        span
 | 
					                span
 | 
				
			||||||
                            transition: 0.2s
 | 
					                  transition: 0.2s
 | 
				
			||||||
                            color: $black
 | 
					                  color: $black
 | 
				
			||||||
                            font-family: "Apercu Mono", monospace
 | 
					                  font-family: "Apercu Mono", monospace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                li:hover
 | 
					                li:hover
 | 
				
			||||||
                    background-color: $black
 | 
					                  background-color: $black
 | 
				
			||||||
                    a
 | 
					                  a
 | 
				
			||||||
                        span
 | 
					                    span
 | 
				
			||||||
                            color: $pink
 | 
					                      color: $pink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                .active
 | 
					                .active
 | 
				
			||||||
                    background-color: $black
 | 
					                  background-color: $black
 | 
				
			||||||
                    a
 | 
					                  a
 | 
				
			||||||
                        span
 | 
					                    span
 | 
				
			||||||
                            color: $green
 | 
					                      color: $green
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                .active:hover
 | 
					                .active:hover
 | 
				
			||||||
                    background-color: $pink
 | 
					                  background-color: $pink
 | 
				
			||||||
                    a
 | 
					                  a
 | 
				
			||||||
                        span
 | 
					                    span
 | 
				
			||||||
                            color: $black
 | 
					                      color: $black
 | 
				
			||||||
main
 | 
					main
 | 
				
			||||||
    padding: 0.5rem
 | 
					  padding: 0.5rem
 | 
				
			||||||
    h1
 | 
					  h1
 | 
				
			||||||
        padding-bottom: 1rem
 | 
					    padding-bottom: 1rem
 | 
				
			||||||
        font-size: 4.5rem
 | 
					    font-size: 4.5rem
 | 
				
			||||||
        span
 | 
					    span
 | 
				
			||||||
            text-decoration: underline $pink
 | 
					      text-decoration: underline $pink
 | 
				
			||||||
            text-decoration-style: wavy
 | 
					      text-decoration-style: wavy
 | 
				
			||||||
    p
 | 
					    p
 | 
				
			||||||
        font-size: 2rem
 | 
					      font-size: 2rem
 | 
				
			||||||
        margin-bottom: 5px
 | 
					      margin-bottom: 5px
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
footer
 | 
					footer
 | 
				
			||||||
    text-align: center
 | 
					  text-align: center
 | 
				
			||||||
    font-size: 1rem
 | 
					  font-size: 1rem
 | 
				
			||||||
    padding: 0.5rem
 | 
					  padding: 0.5rem
 | 
				
			||||||
    a
 | 
					  a
 | 
				
			||||||
        color: $pink
 | 
					    color: $pink
 | 
				
			||||||
        text-decoration: underline $pink
 | 
					    text-decoration: underline $pink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.ef
 | 
					.ef
 | 
				
			||||||
    max-height: 85vh
 | 
					  max-height: 85vh
 | 
				
			||||||
    min-height: 85vh !important
 | 
					  min-height: 85vh !important
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.error
 | 
					.error
 | 
				
			||||||
    text-align: center
 | 
					  text-align: center
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pink-block
 | 
					.pink-block
 | 
				
			||||||
    background-color: $pink
 | 
					  background-color: $pink
 | 
				
			||||||
    min-height: 100vh
 | 
					  min-height: 100vh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.center-v
 | 
					.center-v
 | 
				
			||||||
    min-height: 100%  /* Fallback for browsers do NOT support vh unit */
 | 
					  min-height: 100% /* Fallback for browsers do NOT support vh unit */
 | 
				
			||||||
    min-height: 100vh /* These two lines are counted as one :-)       */
 | 
					  min-height: 100vh /* These two lines are counted as one :-) */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    display: flex
 | 
					  display: flex
 | 
				
			||||||
    align-items: center
 | 
					  align-items: center
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.center-v-h
 | 
					.center-v-h
 | 
				
			||||||
    display: flex
 | 
					  display: flex
 | 
				
			||||||
    justify-content: center
 | 
					  justify-content: center
 | 
				
			||||||
    align-items: center
 | 
					  align-items: center
 | 
				
			||||||
    min-height: 100vh
 | 
					  min-height: 100vh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.logos-container
 | 
					.logos-container
 | 
				
			||||||
    width: 3.5rem
 | 
					  width: 3.5rem
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.logo
 | 
					.logo
 | 
				
			||||||
    width: auto
 | 
					  width: auto
 | 
				
			||||||
    height: 3.5rem
 | 
					  height: 3.5rem
 | 
				
			||||||
    fill: $black
 | 
					  fill: $black
 | 
				
			||||||
    margin-bottom: 2.5rem
 | 
					  margin-bottom: 2.5rem
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.logo-container
 | 
					.logo-container
 | 
				
			||||||
    cursor: pointer
 | 
					  cursor: pointer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.about-pos
 | 
					.about-pos
 | 
				
			||||||
    p
 | 
					  p
 | 
				
			||||||
        font-size: 3vh
 | 
					    font-size: 3vh
 | 
				
			||||||
        margin-bottom: 3vh
 | 
					    margin-bottom: 3vh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pr
 | 
					.pr
 | 
				
			||||||
    img
 | 
					  img
 | 
				
			||||||
        width: 100%
 | 
					    width: 100%
 | 
				
			||||||
        border: 2vh solid $pink
 | 
					    border: 2vh solid $pink
 | 
				
			||||||
    margin-bottom: 3vh
 | 
					    margin-bottom: 3vh
 | 
				
			||||||
    margin-top: 1vh
 | 
					    margin-top: 1vh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
.pr-text
 | 
					.pr-text
 | 
				
			||||||
    a
 | 
					  a
 | 
				
			||||||
        color: $pink
 | 
					    color: $pink
 | 
				
			||||||
        h1
 | 
					    h1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            font-size: 4vh
 | 
					      font-size: 4vh
 | 
				
			||||||
            margin-bottom: 0
 | 
					      margin-bottom: 0
 | 
				
			||||||
            padding-bottom: 0
 | 
					      padding-bottom: 0
 | 
				
			||||||
    a:hover
 | 
					    a:hover
 | 
				
			||||||
        color: $green
 | 
					      color: $green
 | 
				
			||||||
    p
 | 
					    p
 | 
				
			||||||
        font-size: 3vh
 | 
					      font-size: 3vh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.start
 | 
					.start
 | 
				
			||||||
    margin-top: 3vh
 | 
					  margin-top: 3vh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#contact-message
 | 
					#contact-message
 | 
				
			||||||
    margin-top: 2vh
 | 
					  margin-top: 2vh
 | 
				
			||||||
    p
 | 
					  p
 | 
				
			||||||
        color: $green
 | 
					    color: $green
 | 
				
			||||||
        span
 | 
					    span
 | 
				
			||||||
            text-decoration: underline $green
 | 
					      text-decoration: underline $green
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.h-captcha
 | 
					.h-captcha
 | 
				
			||||||
    margin-bottom: 0.5vh
 | 
					  margin-bottom: 0.5vh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.button-c
 | 
					.button-c
 | 
				
			||||||
    display: inline-block
 | 
					  display: inline-block
 | 
				
			||||||
    font-weight: 400
 | 
					  font-weight: 400
 | 
				
			||||||
    color: #212529
 | 
					  color: #212529
 | 
				
			||||||
    text-align: center
 | 
					  text-align: center
 | 
				
			||||||
    vertical-align: middle
 | 
					  vertical-align: middle
 | 
				
			||||||
    cursor: pointer
 | 
					  cursor: pointer
 | 
				
			||||||
    user-select: none
 | 
					  user-select: none
 | 
				
			||||||
    border: 1px solid $black
 | 
					  border: 1px solid $black
 | 
				
			||||||
    padding: 0.375rem 0.75rem
 | 
					  padding: 0.375rem 0.75rem
 | 
				
			||||||
    font-size: 1rem
 | 
					  font-size: 1rem
 | 
				
			||||||
    line-height: 1.5
 | 
					  line-height: 1.5
 | 
				
			||||||
    border-radius: 0.25rem
 | 
					  border-radius: 0.25rem
 | 
				
			||||||
    transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out
 | 
					  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out
 | 
				
			||||||
    font-family: "Apercu Mono"
 | 
					  font-family: "Apercu Mono"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.button-c
 | 
					.button-c
 | 
				
			||||||
    background-color: $pink
 | 
					  background-color: $pink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.button-c:hover
 | 
					.button-c:hover
 | 
				
			||||||
    background-color: $black
 | 
					  background-color: $black
 | 
				
			||||||
    color: $pink
 | 
					  color: $pink
 | 
				
			||||||
    border-color: $pink
 | 
					  border-color: $pink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Nav stuff
 | 
					// Nav stuff
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.ham
 | 
					.ham
 | 
				
			||||||
    width: 30px
 | 
					  width: 30px
 | 
				
			||||||
    height: 20px
 | 
					  height: 20px
 | 
				
			||||||
    position: relative
 | 
					  position: relative
 | 
				
			||||||
    margin: 0px
 | 
					  margin: 0px
 | 
				
			||||||
    -webkit-transform: rotate(0deg)
 | 
					  -webkit-transform: rotate(0deg)
 | 
				
			||||||
    -moz-transform: rotate(0deg)
 | 
					  -moz-transform: rotate(0deg)
 | 
				
			||||||
    -o-transform: rotate(0deg)
 | 
					  -o-transform: rotate(0deg)
 | 
				
			||||||
    transform: rotate(0deg)
 | 
					  transform: rotate(0deg)
 | 
				
			||||||
    -webkit-transition: .5s ease-in-out
 | 
					  -webkit-transition: .5s ease-in-out
 | 
				
			||||||
    -moz-transition: .5s ease-in-out
 | 
					  -moz-transition: .5s ease-in-out
 | 
				
			||||||
    -o-transition: .5s ease-in-out
 | 
					  -o-transition: .5s ease-in-out
 | 
				
			||||||
    transition: .5s ease-in-out
 | 
					  transition: .5s ease-in-out
 | 
				
			||||||
    cursor: pointer
 | 
					  cursor: pointer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.ham span
 | 
					.ham span
 | 
				
			||||||
    display: block
 | 
					  display: block
 | 
				
			||||||
    position: absolute
 | 
					  position: absolute
 | 
				
			||||||
    height: 3px
 | 
					  height: 3px
 | 
				
			||||||
    width: 100%
 | 
					  width: 100%
 | 
				
			||||||
    border-radius: 9px
 | 
					  border-radius: 9px
 | 
				
			||||||
    opacity: 1
 | 
					  opacity: 1
 | 
				
			||||||
    left: 0
 | 
					  left: 0
 | 
				
			||||||
    -webkit-transform: rotate(0deg)
 | 
					  -webkit-transform: rotate(0deg)
 | 
				
			||||||
    -moz-transform: rotate(0deg)
 | 
					  -moz-transform: rotate(0deg)
 | 
				
			||||||
    -o-transform: rotate(0deg)
 | 
					  -o-transform: rotate(0deg)
 | 
				
			||||||
    transform: rotate(0deg)
 | 
					  transform: rotate(0deg)
 | 
				
			||||||
    -webkit-transition: .25s ease-in-out
 | 
					  -webkit-transition: .25s ease-in-out
 | 
				
			||||||
    -moz-transition: .25s ease-in-out
 | 
					  -moz-transition: .25s ease-in-out
 | 
				
			||||||
    -o-transition: .25s ease-in-out
 | 
					  -o-transition: .25s ease-in-out
 | 
				
			||||||
    transition: .25s ease-in-out
 | 
					  transition: .25s ease-in-out
 | 
				
			||||||
    background: $pink
 | 
					  background: $pink
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.ham span:nth-child(1)
 | 
					.ham span:nth-child(1)
 | 
				
			||||||
    top: 0
 | 
					  top: 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.ham span:nth-child(2), .ham span:nth-child(3)
 | 
					.ham span:nth-child(2), .ham span:nth-child(3)
 | 
				
			||||||
    top: 10px
 | 
					  top: 10px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.ham span:nth-child(4)
 | 
					.ham span:nth-child(4)
 | 
				
			||||||
    top: 20px
 | 
					  top: 20px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.ham.open span:nth-child(1)
 | 
					.ham.open span:nth-child(1)
 | 
				
			||||||
    top: 11px
 | 
					  top: 11px
 | 
				
			||||||
    width: 0
 | 
					  width: 0
 | 
				
			||||||
    left: 50%
 | 
					  left: 50%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.ham.open span:nth-child(2)
 | 
					.ham.open span:nth-child(2)
 | 
				
			||||||
    -webkit-transform: rotate(45deg)
 | 
					  -webkit-transform: rotate(45deg)
 | 
				
			||||||
    -moz-transform: rotate(45deg)
 | 
					  -moz-transform: rotate(45deg)
 | 
				
			||||||
    -o-transform: rotate(45deg)
 | 
					  -o-transform: rotate(45deg)
 | 
				
			||||||
    transform: rotate(45deg)
 | 
					  transform: rotate(45deg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.ham.open span:nth-child(3)
 | 
					.ham.open span:nth-child(3)
 | 
				
			||||||
    -webkit-transform: rotate(-45deg)
 | 
					  -webkit-transform: rotate(-45deg)
 | 
				
			||||||
    -moz-transform: rotate(-45deg)
 | 
					  -moz-transform: rotate(-45deg)
 | 
				
			||||||
    -o-transform: rotate(-45deg)
 | 
					  -o-transform: rotate(-45deg)
 | 
				
			||||||
    transform: rotate(-45deg)
 | 
					  transform: rotate(-45deg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.ham.open span:nth-child(4)
 | 
					.ham.open span:nth-child(4)
 | 
				
			||||||
    top: 11px
 | 
					  top: 11px
 | 
				
			||||||
    width: 0
 | 
					  width: 0
 | 
				
			||||||
    left: 50%
 | 
					  left: 50%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@media only screen and (max-height: 421px)
 | 
					@media only screen and (max-height: 421px)
 | 
				
			||||||
    .pr-text
 | 
					  .pr-text
 | 
				
			||||||
        margin-bottom: 5vh !important
 | 
					    margin-bottom: 5vh !important
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@media only screen and (max-width: 575px)
 | 
					@media only screen and (max-width: 575px)
 | 
				
			||||||
    .logo
 | 
					  .logo
 | 
				
			||||||
        height: 5rem
 | 
					    height: 5rem
 | 
				
			||||||
    .logos-container
 | 
					    .logos-container
 | 
				
			||||||
        width: 5rem
 | 
					      width: 5rem
 | 
				
			||||||
    .aaa
 | 
					    .aaa
 | 
				
			||||||
        min-height: 40vh !important
 | 
					      min-height: 40vh !important
 | 
				
			||||||
    .aaaa
 | 
					    .aaaa
 | 
				
			||||||
        margin-top: 5vh !important
 | 
					      margin-top: 5vh !important
 | 
				
			||||||
    .ef
 | 
					    .ef
 | 
				
			||||||
        max-height: none !important
 | 
					      max-height: none !important
 | 
				
			||||||
        min-height: 0 !important
 | 
					      min-height: 0 !important
 | 
				
			||||||
    .ff
 | 
					    .ff
 | 
				
			||||||
        min-height: 82.8vh !important
 | 
					      min-height: 82.8vh !important
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
@media only screen and (max-height: 815px)
 | 
					@media only screen and (max-height: 815px)
 | 
				
			||||||
    .ef
 | 
					  .ef
 | 
				
			||||||
        max-height: none !important
 | 
					    max-height: none !important
 | 
				
			||||||
        min-height: 0 !important
 | 
					    min-height: 0 !important
 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,25 +3,35 @@ const axios = require('axios');
 | 
				
			|||||||
var router = express.Router();
 | 
					var router = express.Router();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* GET home page. */
 | 
					/* GET home page. */
 | 
				
			||||||
router.get('/', function(req, res, next) {
 | 
					router.get('/', function (req, res, _next) {
 | 
				
			||||||
    const GHOST_KEY = process.env.GHOST_KEY
 | 
					  const GHOST_KEY = process.env.GHOST_KEY;
 | 
				
			||||||
    const base_url = `https://blog.pastel.codes/ghost/api/v3/content/posts/?key=${GHOST_KEY}`
 | 
					  const base_url = `https://blog.pastel.codes/ghost/api/v3/content/posts/?key=${GHOST_KEY}`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    axios.all([
 | 
					  axios
 | 
				
			||||||
        axios.get(`${base_url}&limit=3`),
 | 
					    .all([
 | 
				
			||||||
        axios.get(`${base_url}&limit=3&filter=tag:project`),
 | 
					      axios.get(`${base_url}&limit=3`),
 | 
				
			||||||
 | 
					      axios.get(`${base_url}&limit=3&filter=tag:project`),
 | 
				
			||||||
    ])
 | 
					    ])
 | 
				
			||||||
        .then(axios.spread((response1, response2) => {
 | 
					    .then(
 | 
				
			||||||
            var base = { title: 'About', description: 'Who??? What??? AAAAaaa, about me.'};
 | 
					      axios.spread((response1, response2) => {
 | 
				
			||||||
            var blog = JSON.parse(JSON.stringify(response1.data).split('"posts":').join('"blog":'));
 | 
					        var base = {
 | 
				
			||||||
            var projects = JSON.parse(JSON.stringify(response2.data).split('"posts":').join('"project":'));
 | 
					          title: 'About',
 | 
				
			||||||
            var out = Object.assign(base, blog, projects);
 | 
					          description: 'Who??? What??? AAAAaaa, about me.',
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					        var blog = JSON.parse(
 | 
				
			||||||
 | 
					          JSON.stringify(response1.data).split('"posts":').join('"blog":')
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        var projects = JSON.parse(
 | 
				
			||||||
 | 
					          JSON.stringify(response2.data).split('"posts":').join('"project":')
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        var out = Object.assign(base, blog, projects);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            res.render('about', out);
 | 
					        res.render('about', out);
 | 
				
			||||||
        }))
 | 
					      })
 | 
				
			||||||
        .catch(error => {
 | 
					    )
 | 
				
			||||||
            console.log(error);
 | 
					    .catch((error) => {
 | 
				
			||||||
        });
 | 
					      console.log(error);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = router;
 | 
					module.exports = router;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,73 +1,80 @@
 | 
				
			|||||||
var express = require('express');
 | 
					var express = require('express');
 | 
				
			||||||
var rate_limit = require("express-rate-limit")
 | 
					var rate_limit = require('express-rate-limit');
 | 
				
			||||||
const {verify} = require('hcaptcha');
 | 
					const { verify } = require('hcaptcha');
 | 
				
			||||||
const nodemailer = require('nodemailer')
 | 
					 | 
				
			||||||
var router = express.Router();
 | 
					var router = express.Router();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const sgMail = require('@sendgrid/mail');
 | 
					const sgMail = require('@sendgrid/mail');
 | 
				
			||||||
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
 | 
					sgMail.setApiKey(process.env.SENDGRID_API_KEY);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const contact_rate_limit = rate_limit({
 | 
					const contact_rate_limit = rate_limit({
 | 
				
			||||||
    windowMs: 10 * 60 * 1000, // 10 minutes
 | 
					  windowMs: 10 * 60 * 1000, // 10 minutes
 | 
				
			||||||
    max: 5, // limit each IP to 10 requests per windowMs
 | 
					  max: 5, // limit each IP to 10 requests per windowMs
 | 
				
			||||||
    message: "Too many contact requests, try again later.",
 | 
					  message: 'Too many contact requests, try again later.',
 | 
				
			||||||
    handler: function (req, res /*, next*/) {
 | 
					  handler: function (req, res /*, next*/) {
 | 
				
			||||||
        res.render('error', {
 | 
					    res.render('error', {
 | 
				
			||||||
            title: "Error",
 | 
					      title: 'Error',
 | 
				
			||||||
            message: "Too many contact requests, try again later.",
 | 
					      message: 'Too many contact requests, try again later.',
 | 
				
			||||||
            error: {status: null}
 | 
					      error: { status: null },
 | 
				
			||||||
        })
 | 
					    });
 | 
				
			||||||
    },
 | 
					  },
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// POST route from contact form
 | 
					// POST route from contact form
 | 
				
			||||||
router.post('/', contact_rate_limit, (req, res) => {
 | 
					router.post('/', contact_rate_limit, (req, res) => {
 | 
				
			||||||
    const TO_MAIL_USER = process.env.TO_MAIL_USER
 | 
					  const TO_MAIL_USER = process.env.TO_MAIL_USER;
 | 
				
			||||||
    const FROM_MAIL_USER = process.env.FROM_MAIL_USER
 | 
					  const FROM_MAIL_USER = process.env.FROM_MAIL_USER;
 | 
				
			||||||
    const HCAPTCHA_KEY = process.env.HCAPTCHA_KEY
 | 
					  const HCAPTCHA_KEY = process.env.HCAPTCHA_KEY;
 | 
				
			||||||
    const REPLY_TO_MAIL = process.env.REPLY_TO_MAIL
 | 
					  const REPLY_TO_MAIL = process.env.REPLY_TO_MAIL;
 | 
				
			||||||
    const token = req.body["g-recaptcha-response"];
 | 
					  const token = req.body['g-recaptcha-response'];
 | 
				
			||||||
    const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
 | 
					  const ip = req.headers['x-forwarded-for'] || req.connection.remoteAddress;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    verify(HCAPTCHA_KEY, token)
 | 
					  verify(HCAPTCHA_KEY, token)
 | 
				
			||||||
        .then((data) => {
 | 
					    .then((data) => {
 | 
				
			||||||
            if (data.success === true) {
 | 
					      if (data.success === true) {
 | 
				
			||||||
                const msg = {
 | 
					        const msg = {
 | 
				
			||||||
                    to: TO_MAIL_USER,
 | 
					          to: TO_MAIL_USER,
 | 
				
			||||||
                    from: FROM_MAIL_USER,
 | 
					          from: FROM_MAIL_USER,
 | 
				
			||||||
                    subject: 'New message from contact form at pastel.codes',
 | 
					          subject: 'New message from contact form at pastel.codes',
 | 
				
			||||||
                    text: `${req.body.firstname} ${req.body.lastname} (${req.body.email})\nsays: ${req.body.message}\n\nip: ${ip}`
 | 
					          text: `${req.body.firstname} ${req.body.lastname} (${req.body.email})\nsays: ${req.body.message}\n\nip: ${ip}`,
 | 
				
			||||||
                };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                sgMail
 | 
					        sgMail
 | 
				
			||||||
                    .send(msg)
 | 
					          .send(msg)
 | 
				
			||||||
                    .then(() => {
 | 
					          .then(() => {
 | 
				
			||||||
                        res.render('contact', {
 | 
					            res.render('contact', {
 | 
				
			||||||
                            title: 'Contact',
 | 
					              title: 'Contact',
 | 
				
			||||||
                            message: "I will get back to you soon!",
 | 
					              message: 'I will get back to you soon!',
 | 
				
			||||||
                            success: "Make sure the email is from ",
 | 
					              success: 'Make sure the email is from ',
 | 
				
			||||||
                            email: REPLY_TO_MAIL
 | 
					              email: REPLY_TO_MAIL,
 | 
				
			||||||
                        })
 | 
					            });
 | 
				
			||||||
                    })
 | 
					          })
 | 
				
			||||||
                    .catch(error => {
 | 
					          .catch((error) => {
 | 
				
			||||||
                        console.log(error)
 | 
					 | 
				
			||||||
                        res.render('error', {title: 'Contact', message: "Email did not send"})
 | 
					 | 
				
			||||||
                    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                // rerender with same info in the text box and show error message
 | 
					 | 
				
			||||||
                res.render('contact', {title: 'Contact', message: "Captcha failed, try again"});
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        })
 | 
					 | 
				
			||||||
        .catch(error => {
 | 
					 | 
				
			||||||
            console.log(error);
 | 
					            console.log(error);
 | 
				
			||||||
            res.render('contact', {title: 'Contact', message: "Something wrong happened, try again later"});
 | 
					            res.render('error', {
 | 
				
			||||||
 | 
					              title: 'Contact',
 | 
				
			||||||
 | 
					              message: 'Email did not send',
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        // rerender with same info in the text box and show error message
 | 
				
			||||||
 | 
					        res.render('contact', {
 | 
				
			||||||
 | 
					          title: 'Contact',
 | 
				
			||||||
 | 
					          message: 'Captcha failed, try again',
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
})
 | 
					      }
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    .catch((error) => {
 | 
				
			||||||
 | 
					      console.log(error);
 | 
				
			||||||
 | 
					      res.render('contact', {
 | 
				
			||||||
 | 
					        title: 'Contact',
 | 
				
			||||||
 | 
					        message: 'Something wrong happened, try again later',
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* GET home page. */
 | 
					/* GET home page. */
 | 
				
			||||||
router.get('/', function (req, res, next) {
 | 
					router.get('/', function (req, res, _next) {
 | 
				
			||||||
    res.render('contact', {title: 'Contact', description: "Contact me!"});
 | 
					  res.render('contact', { title: 'Contact', description: 'Contact me!' });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = router;
 | 
					module.exports = router;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,8 +2,8 @@ var express = require('express');
 | 
				
			|||||||
var router = express.Router();
 | 
					var router = express.Router();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* GET home page. */
 | 
					/* GET home page. */
 | 
				
			||||||
router.get('/', function(req, res, next) {
 | 
					router.get('/', function (req, res, _next) {
 | 
				
			||||||
    res.render('index', { title: 'Home', description: "Hello, I'm E" });
 | 
					  res.render('index', { title: 'Home', description: "Hello, I'm E" });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = router;
 | 
					module.exports = router;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,23 +2,23 @@
 | 
				
			|||||||
@tailwind components;
 | 
					@tailwind components;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@font-face {
 | 
					@font-face {
 | 
				
			||||||
    font-family: 'Titling Gothic FB';
 | 
					  font-family: 'Titling Gothic FB';
 | 
				
			||||||
    src: url("../fonts/TITLINGGOTHICFB-WIDE.OTF") format('opentype')
 | 
					  src: url('../fonts/TITLINGGOTHICFB-WIDE.OTF') format('opentype');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@font-face {
 | 
					@font-face {
 | 
				
			||||||
    font-family: 'Gilroy';
 | 
					  font-family: 'Gilroy';
 | 
				
			||||||
    src: url("../fonts/Gilroy-ExtraBold.otf") format('opentype')
 | 
					  src: url('../fonts/Gilroy-ExtraBold.otf') format('opentype');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@font-face {
 | 
					@font-face {
 | 
				
			||||||
    font-family: 'Apercu Mono';
 | 
					  font-family: 'Apercu Mono';
 | 
				
			||||||
    src: url("../fonts/ApercuMono.ttf") format('truetype');
 | 
					  src: url('../fonts/ApercuMono.ttf') format('truetype');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.wavy {
 | 
					.wavy {
 | 
				
			||||||
    text-decoration: underline;
 | 
					  text-decoration: underline;
 | 
				
			||||||
    text-decoration-style: wavy;
 | 
					  text-decoration-style: wavy;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@tailwind utilities;
 | 
					@tailwind utilities;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +1,13 @@
 | 
				
			|||||||
module.exports = {
 | 
					module.exports = {
 | 
				
			||||||
  mode: "jit",
 | 
					  mode: 'jit',
 | 
				
			||||||
  purge: ['views/*.pug'],
 | 
					  purge: ['views/*.pug'],
 | 
				
			||||||
  darkMode: false, // or 'media' or 'class'
 | 
					  darkMode: false, // or 'media' or 'class'
 | 
				
			||||||
  theme: {
 | 
					  theme: {
 | 
				
			||||||
    extend: {
 | 
					    extend: {
 | 
				
			||||||
      fontFamily: {
 | 
					      fontFamily: {
 | 
				
			||||||
        'extra': ['"Titling Gothic FB"'],
 | 
					        extra: ['"Titling Gothic FB"'],
 | 
				
			||||||
        'sans': ['Gilroy'],
 | 
					        sans: ['Gilroy'],
 | 
				
			||||||
        'mono': ['"Apercu Mono"'],
 | 
					        mono: ['"Apercu Mono"'],
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      colors: {
 | 
					      colors: {
 | 
				
			||||||
        transparent: 'transparent',
 | 
					        transparent: 'transparent',
 | 
				
			||||||
@@ -20,14 +20,12 @@ module.exports = {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
        green: {
 | 
					        green: {
 | 
				
			||||||
          DEFAULT: '#CDE7B0',
 | 
					          DEFAULT: '#CDE7B0',
 | 
				
			||||||
        }
 | 
					        },
 | 
				
			||||||
      }
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  variants: {
 | 
					  variants: {
 | 
				
			||||||
    extend: {},
 | 
					    extend: {},
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  plugins: [
 | 
					  plugins: [require('tailwind-hamburgers')],
 | 
				
			||||||
    require('tailwind-hamburgers'),
 | 
					};
 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user