Commit d5d9e506 authored by Wolfgang Knopki's avatar Wolfgang Knopki
Browse files

Merge branch 'prepare_prod' into 'master'

deployment

See merge request !85
parents 72ac8766 61a3dfc5
Pipeline #5333 passed with stage
in 11 seconds
/node_modules
sp-project-metadata.xml
sp-project-metadata-m4lab.xml
/built
/node_modules
\ No newline at end of file
pages-testing:
stage: deploy
script:
- cat $configfiledev > ./config/config.js
- npm install
- npm run clean
- npm run build
- rm -rf ./built/views
- cp -R ./views ./built
- cat $configfiledev > ./built/config/config.js
- "pm2 delete --silent project || :"
- pm2 start ./app.js --name=project
- pm2 start ./built/app.js --name=project
- pm2 save
tags:
- testing
......@@ -14,12 +18,17 @@ pages-testing:
pages-production:
stage: deploy
script:
- cat $configfileprod > ./config/config.js
script:
- npm install
- npm run clean
- npm run build
- rm -rf ./built/views
- cp -R ./views ./built
- cat $configfileprod > ./built/config/config.js
- "pm2 delete --silent project || :"
- pm2 start ./app.js --name=project
- pm2 start ./built/app.js --name=project
- pm2 save
tags:
- production
only:
- master
\ No newline at end of file
- master
const gitlab = require('../functions/gitlab')
describe('GitLab API', () => {
test('get all projects', async () => {
let projects = await gitlab.getProjects(10, 0)
expect(projects).not.toBeNull()
})
test('get latest pipeline status of a project', async () => {
let status = await gitlab.getLatestPipelineStatus(81)
expect(status).not.toBeNull()
})
})
\ No newline at end of file
const methods = require('../functions/methods')
describe('DB methods', () => {
test('all mailinglists', async () => {
let lists = await methods.getAllMailinglists(0)
expect(lists).not.toBeNull()
})
test('project overview', async () => {
let overview = await methods.getProjectOverviewById(81)
expect(overview).not.toBeNull()
})
test('project images', async () => {
let images = await methods.getProjectImagesById(81)
expect(images).not.toBeNull()
})
})
\ No newline at end of file
const express = require('express')
const path = require('path')
const passport = require('passport')
const morgan = require('morgan')
const cookieParser = require('cookie-parser')
const bodyParser = require('body-parser')
const session = require('express-session')
const flash = require('express-flash')
const fileUpload = require('express-fileupload')
const helmet = require('helmet')
const compression = require('compression')
import express from 'express'
import path from 'path'
//import passport from 'passport'
import morgan from 'morgan'
import cookieParser from 'cookie-parser'
import bodyParser from 'body-parser'
//import session from 'express-session'
//import flash from 'express-flash'
//import fileUpload from 'express-fileupload'
import helmet from 'helmet'
import compression from 'compression'
var env = process.env.NODE_ENV || 'production'
var env = process.env.NODE_ENV || 'testing'
const config = require('./config/config')[env]
const lang = 'DE';
var app = express()
app.set('port', config.app.port)
app.set('views', __dirname + '/views')
app.set('view engine', 'pug')
app.use(helmet())
app.use(
helmet.contentSecurityPolicy({
useDefaults: true,
directives: {
"font-src": ["'self'", "https://use.fontawesome.com"],
"img-src": ["'self'", "https://transfer.hft-stuttgart.de"],
"script-src": ["'self'", "https://code.jquery.com/jquery-3.3.1.min.js", "https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js", "https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"],
"style-src": ["'self'", "https://use.fontawesome.com/releases/v5.8.2/css/all.css"],
"frame-src": ["'self'"]
},
reportOnly: true,
})
);
app.use(compression())
app.use(morgan('combined'))
app.use(cookieParser())
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended: false}))
app.use(express.static(path.join(__dirname, 'public')))
app.use(session(
/*app.use(session(
{
resave: true,
saveUninitialized: true,
//secret: config.app.sessionSecret
secret: 'thisisasecret-thisisasecret-thisisasecret'
}
))
app.use(passport.initialize())
app.use(passport.session())
app.use(flash())
app.use(passport.session()) */
/*app.use(flash())
app.use((req, res, next) => {
res.locals.errors = req.flash("error")
res.locals.successes = req.flash("success")
next()
})
}) */
// enable files upload
app.use(fileUpload({
/*app.use(fileUpload({
createParentPath: true,
limits: {
fileSize: 1000000 // 1 MB max. file size
}
}))
})) */
// caching disabled for every route
// NOTE: Works in Firefox and Opera. Does not work in Edge
app.use(function(req, res, next) {
......@@ -55,22 +68,21 @@ app.use(function(req, res, next) {
next()
})
require('./routes/routes-project')(app, config, passport)
require('./routes/project')(app, lang)
// Handle 404
app.use(function (req, res, next) {
res.status(404).render('./DE/404')
app.use(function (req:any, res:any) {
res.status(404).render(lang+'/404')
})
// Handle 500 - any server error
app.use(function (err, req, res, next) {
app.use(function (err:any, req:any, res:any, next:any) {
console.error(err.stack)
res.status(500).render('./DE/500', {
res.status(500).render(lang+'/500', {
error: err
})
})
app.listen(app.get('port'), function () {
console.log('Project Page listening on port ' + app.get('port'))
console.log(__dirname)
})
\ No newline at end of file
......@@ -4,16 +4,8 @@ module.exports = {
name: 'Project Page Manager',
port: process.env.PORT || 8888
},
passport: {
strategy: 'saml',
saml: {
path: process.env.SAML_PATH || '/saml/SSO',
entryPoint: process.env.SAML_ENTRY_POINT || 'saml entry URL',
issuer: 'saml issuer URL',
logoutUrl: 'saml Logout URL'
}
},
database: {
host: 'localhost',
user: 'usernamedb', // DB username
password: 'passworddb', // DB password
port: 3306, // MySQL port
......@@ -21,15 +13,6 @@ module.exports = {
host_project: 'localhost', // local
dbProject: 'projectdb' // Project DB
},
mailer: {
host: 'mailhost', // hostname
secureConnection: false, // TLS requires secureConnection to be false
port: 587, // port for secure SMTP
authUser: 'usernamemail',
authPass: 'passwordmail',
tlsCiphers: 'SSLv3',
from: 'email_from',
},
gitlab: {
token_readWriteProjects: 'putyourtokenhere'
}
......@@ -39,16 +22,8 @@ module.exports = {
name: 'Project Page Manager',
port: process.env.PORT || 8888
},
passport: {
strategy: 'saml',
saml: {
path: process.env.SAML_PATH || '/saml/SSO',
entryPoint: process.env.SAML_ENTRY_POINT || 'saml entry URL',
issuer: 'saml issuer URL',
logoutUrl: 'saml Logout URL'
}
},
database: {
host: 'localhost',
user: 'usernamedb', // DB username
password: 'passworddb', // DB password
port: 3306, // MySQL port
......@@ -56,15 +31,6 @@ module.exports = {
host_project: 'localhost', // local
dbProject: 'projectdb' // Project DB
},
mailer: {
host: 'mailhost', // hostname
secureConnection: false, // TLS requires secureConnection to be false
port: 587, // port for secure SMTP
authUser: 'usernamemail',
authPass: 'passwordmail',
tlsCiphers: 'SSLv3',
from: 'email_from',
},
gitlab: {
token_readWriteProjects: 'putyourtokenhere'
}
......
const mysql = require('mysql')
import mysql from 'mysql2'
var env = process.env.NODE_ENV || 'production';
const config = require('../config/config')[env]
var env = process.env.NODE_ENV || 'testing';
const config = require('./config')[env]
// ==== USER ACOOUNT DB CONNECTION ====
var userConnection = mysql.createConnection({
const userConnection = mysql.createPool({
host: config.database.host,
user: config.database.user,
password: config.database.password,
port: config.database.port,
database: config.database.dbUser,
multipleStatements: true
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
})
userConnection.connect(function(err) {
if (err) throw err;
})
userConnection.query('USE '+config.database.dbUser)
// user db connection test
userConnection.query('SELECT 1 + 5 AS solution', function (err, rows, fields) {
if (err) throw err
console.log('Solution = ', rows[0].solution)
})
//userConnection.end()
// ==== PROJECT DB CONNECTION ====
var projectConnection = mysql.createConnection({
const projectConnection = mysql.createPool({
host: config.database.host_project,
user: config.database.user,
password: config.database.password,
port: config.database.port,
database: config.database.dbProject
database: config.database.dbProject,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
})
projectConnection.connect(function(err) {
if (err) throw err;
})
projectConnection.query('USE '+config.database.dbProject)
// projectdb connection test
projectConnection.query('SELECT 10 + 5 AS project', function (err, rows, fields) {
if (err) throw err
console.log('Project = ', rows[0].project)
})
//projectConnection.end()
var connection = {
const connection = {
user: userConnection,
project: projectConnection
}
module.exports = connection
\ No newline at end of file
export = connection
\ No newline at end of file
const axios = require('axios')
import axios from 'axios'
var gitlab = {
getProjects: async function(perPage, idAfter) {
getProjects: async function(perPage:number, idAfter:number) {
try {
let projects = await axios({
method: 'get',
......@@ -30,7 +30,7 @@ var gitlab = {
data: err}
}
},
getLatestPipelineStatus: async function(projectId) {
getLatestPipelineStatus: async function(projectId:number) {
return axios({
method: 'get',
url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/'+projectId+'/pipelines'
......@@ -40,4 +40,4 @@ var gitlab = {
}
}
module.exports = gitlab
\ No newline at end of file
export = gitlab
\ No newline at end of file
var helpers = {
stringToArray: function (input){
stringToArray: function (input:string){
if(input != null){
return input.split(',');
}else{
......@@ -8,4 +8,4 @@ var helpers = {
}
};
module.exports = helpers;
\ No newline at end of file
export = helpers;
\ No newline at end of file
const dbconn = require('../config/dbconn');
var methods = {
getAllMailinglists: async function() {
try {
let rows:any = await dbconn.project.promise().query('CALL getAllLists')
if (rows[0][0]) {
return rows[0][0]
} else { return null }
} catch (err) {
console.error(err)
}
return null
},
getProjectOverviewById: async function(projectId:number) {
try {
let rows:any = await dbconn.project.promise().query('CALL GetProjectInformationByProjectID(' + projectId+ ')')
if (rows[0][0]) {
return rows[0][0]
} else { return null }
} catch (err) {
console.error(err)
}
return null
},
getProjectImagesById: async function(projectId:number) {
try {
let rows:any = await dbconn.project.promise().query('CALL getImagesByProjectID(' + projectId+ ')')
if (rows[0][0]) {
return rows[0][0]
} else { return null }
} catch (err) {
console.error(err)
}
return null
}
};
export = methods;
\ No newline at end of file
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};
\ No newline at end of file
This diff is collapsed.
......@@ -14,8 +14,10 @@
"url": "https://transfer.hft-stuttgart.de/gitlab/m4lab_tv1/project-page.git"
},
"scripts": {
"start": "nodemon app.js",
"test": ""
"start": "nodemon app.ts",
"build": "tsc -build",
"clean": "tsc -build --clean",
"test": "jest"
},
"dependencies": {
"async": "^3.2.0",
......@@ -23,21 +25,31 @@
"body-parser": "^1.19.0",
"compression": "^1.7.4",
"cookie-parser": "1.4.3",
"errorhandler": "1.4.3",
"express": "^4.17.1",
"express-fileupload": "^1.1.7-alpha.2",
"express-flash": "0.0.2",
"express-session": "^1.17.1",
"fs": "0.0.1-security",
"helmet": "^3.23.3",
"helmet": "^4.6.0",
"morgan": "^1.10.0",
"mysql": "^2.18.1",
"passport": "0.3.2",
"passport-saml": "^2.0.6",
"mysql2": "^2.2.5",
"pug": "^3.0.2"
},
"engines": {
"node": ">= 4.0.0"
},
"license": "MIT"
"license": "MIT",
"devDependencies": {
"@types/async": "^3.2.6",
"@types/compression": "^1.7.0",
"@types/cookie-parser": "^1.4.2",
"@types/express": "^4.17.12",
"@types/express-fileupload": "^1.1.6",
"@types/express-flash": "^0.0.2",
"@types/express-session": "^1.17.3",
"@types/jest": "^26.0.24",
"@types/morgan": "^1.9.2",
"@types/passport": "^1.0.6",
"jest": "^27.0.6",
"nodemon": "^2.0.9",
"ts-jest": "^27.0.3",
"ts-node": "^10.0.0",
"typescript": "^4.3.5"
}
}
const nodemailer = require('nodemailer')
var env = process.env.NODE_ENV || 'testing';
const config = require('../config/config')[env]
var smtpTransport = nodemailer.createTransport({
host: config.mailer.host,
secureConnection: config.mailer.secureConnection,
port: config.mailer.port,
auth: {
user: config.mailer.authUser,
pass: config.mailer.authPass
},
tls: {
ciphers: config.mailer.tlsCiphers
}
});
var mailOptions = {
to: "",
from: config.mailer.from,
subject: "",
text: ""
};
var mailer = {
transport: smtpTransport,
options: mailOptions
}
module.exports = mailer
\ No newline at end of file
const dbconn = require('./dbconn');
var methods = {
// test method
currentDate: function() {
console.log('Current Date is: ' + new Date().toISOString().slice(0, 10));
},
// ===================== user db =====================
getUserIdByEmail: function(email, callback) {
var userId
dbconn.user.query('SELECT id FROM user WHERE email = "' +email+'"', function (err, rows, fields) {
if (err) {
throw err;
}
else {
if ( rows.length > 0) {
userId = rows[0].id;
}
}
callback(userId, err);
});
},
/*
getUserProjectRole: function(userId, callback) {
dbconn.user.query('SELECT project_id, role_id FROM user_project_role WHERE user_id = "' +userId+'"', function (err, rows, fields) {
if (err) throw err;
callback(rows, err);
});
},
*/
addUserProjectRole: function(data, callback) {
dbconn.user.query('INSERT INTO user_project_role SET ?', data, function (err, results, fields){
if (err) throw err;
callback(err);
})
},
// ======================= project db =======================
getAllProjects: function(callback) {
dbconn.project.query('CALL getAllprojects', function (err, rows, fields){
if (err) throw err;
callback(rows[0], err);
})
},
getAllMailinglists: function(callback) {
dbconn.project.query('CALL getAllLists', function (err, rows, fields){
if (err) throw err;
callback(rows[0], err);
})
},
getProjectOverviewById: function(projectId, callback) {
dbconn.project.query('CALL GetProjectInformationByProjectID(' + projectId+ ')', function (err, rows, fields){
if (err) throw err;
callback(rows[0], err);
})
},
getProjectImagesById: function(projectId, callback) {
dbconn.project.query('CALL getImagesByProjectID(' + projectId+ ')', function (err, rows, fields){
if (err) throw err;
callback(rows[0], err);
})
},
addProjectOverview: function(data, callback) {
dbconn.project.query('INSERT INTO project_overview SET ?', data, function (err, results, fields){
if (err) {
console.error(err);
}
callback(results, err);
})
}
};
module.exports = methods;
\ No newline at end of file
//const SamlStrategy = require('passport-saml').Strategy
import methods from '../functions/methods'
import gitlab from '../functions/gitlab'
import helpers from '../functions/helpers'
import https from 'https'
module.exports = function (app:any, lang:string) {
// ======== APP ROUTES - PROJECT ====================
app.get('/', function (req:any, res:any) {
res.render(lang+'/project/project-simplified')
})
app.get('/mailinglists', async function (req:any, res:any) {
let mailList = await methods.getAllMailinglists()
if (mailList) {
let allMailingLists = [] // JSON object
for (let i = 0; i < mailList.length; i++) {
// add data to JSON object
allMailingLists.push({
id: mailList[i].id,