Commit 9fb60ffd authored by Rosanny Sihombing's avatar Rosanny Sihombing
Browse files

Merge branch 'devel' into 'testing'

Refactoring and codes cleaning

See merge request !144
parents 961ab112 4450156e
Pipeline #6621 failed with stage
in 20 seconds
{
"presets": [
"@babel/preset-env", "@babel/preset-typescript", "minify"
]
}
\ No newline at end of file
/built
/routes/cert
/src/routes/cert
/node_modules
const dbController = require('../../src/controller/dbController')
describe('DB methohds test', () => {
it('returns a user from DB by email', async () => {
const user = await dbController.getUserByEmail('litehon958@whipjoy.com')
expect(user).not.toBeNull()
})
it('returns a null user', async () => {
const user = await dbController.getUserByEmail('jondoe@nowhere.com') // a non-exist user
expect(user).toBeNull()
})
it("returns a user's email", async () => {
const email = await dbController.getUserEmailById(1)
expect(email).not.toBeNull()
})
it("returns null instead of a user's email", async () => {
const email = await dbController.getUserEmailById(1005) // no user has this ID
expect(email).toBeNull()
})
it('returns null from DB by token', async () => {
const user = await dbController.getUserByToken('12345678') // unvalid token
expect(user).toBeNull() // for valid token = expect(user).not.toBeNull()
})
it("returns a user's verification token, if any", async () => {
const token = await dbController.getVerificationTokenByUserId(1)
expect(token).toBeNull()
})
it("returns a user's ID, if any", async () => {
const token = await dbController.getUserIdByVerificationToken('12345678') // unvalid token
expect(token).toBeNull() // for valid token = expect(user).not.toBeNull()
})
it("returns a user's GitLab_ID, if any", async () => {
const id = await dbController.getGitlabId(1)
expect(id).not.toBeNull()
})
it('checks user email', async () => {
const user = await dbController.checkUserEmail('litehon958@whipjoy.com')
expect(user).not.toBeNull()
})
it('checks user email and return null', async () => {
const user = await dbController.checkUserEmail('jondoe@nowhere.com') // a non-exist user
expect(user).toBeNull()
})
})
import gitlab from '../functions/gitlab'
//const axios = require('axios')
//jest.mock('axios')
const gitlabController = require('../src/controller/gitlabController')
const axios = require('axios')
jest.mock('axios')
describe('GitLab API', () => {
test('returns an existing gitlab user by an email address', async () => {
let user = await gitlab.getUserByEmail('litehon958@whipjoy.com')
axios.get.mockResolvedValue({
})
const user = await gitlabController.getUserByEmail('litehon958@whipjoy.com')
expect(user).not.toBeNull()
})
test('returns an undefined user', async () => {
let user = await gitlab.getUserByEmail('johndoe@nowhere.com')
const user = await gitlabController.getUserByEmail('johndoe@nowhere.com')
expect(user).toBeUndefined()
})
test('returns users project', async () => {
let userProjects = await gitlab.getUserProjects(136)
const userProjects = await gitlabController.getUserProjects(136)
expect(userProjects).toBeDefined()
})
test('returns undefined projects, due to non-existing gitlab user ID', async () => {
let userProjects = await gitlab.getUserProjects(0)
const userProjects = await gitlabController.getUserProjects(0)
expect(userProjects).toBeUndefined()
})
test('returns a project by ID', async () => {
let project = await gitlab.getProjectById(13) // m4lab_landing_page
const project = await gitlabController.getProjectById(13) // m4lab_landing_page
expect(project).toBeDefined()
})
test('returns undefined, due to invalid project ID', async () => {
let project = await gitlab.getProjectById(0)
const project = await gitlabController.getProjectById(0)
expect(project).toBeUndefined()
})
})
\ No newline at end of file
})
const request = require('supertest')
const express = require('express')
const app = express()
app.set('port', 9989)
describe('Test endpoint(s)', () => {
it('should return a 200 status code', () => {
request(app)
.get('/contact')
.expect(200)
.end(function (err, res) {
if (err) throw err
})
})
})
import methods from '../functions/methods'
describe("DB methohds test", () => {
it("returns a user from DB by email", async() => {
const user = await methods.getUserByEmail('litehon958@whipjoy.com')
expect(user).not.toBeNull()
})
it("returns a null user", async() => {
const user = await methods.getUserByEmail('jondoe@nowhere.com') // a non-exist user
expect(user).toBeNull()
})
it("returns a user's email", async() => {
const email = await methods.getUserEmailById(1)
expect(email).not.toBeNull()
})
it("returns null instead of a user's email", async() => {
const email = await methods.getUserEmailById(1005) // no user has this ID
expect(email).toBeNull()
})
it("returns null from DB by token", async() => {
const user = await methods.getUserByToken('12345678') // unvalid token
expect(user).toBeNull() // for valid token = expect(user).not.toBeNull()
})
it("returns a user's verification token, if any", async() => {
const token = await methods.getVerificationTokenByUserId(1)
expect(token).toBeNull()
})
it("returns a user's ID, if any", async() => {
const token = await methods.getUserIdByVerificationToken('12345678') // unvalid token
expect(token).toBeNull() // for valid token = expect(user).not.toBeNull()
})
it("returns a user's GitLab_ID, if any", async() => {
const id = await methods.getGitlabId(1)
expect(id).not.toBeNull()
})
it("checks user email", async() => {
const user = await methods.checkUserEmail('litehon958@whipjoy.com')
expect(user).not.toBeNull()
})
it("checks user email and return null", async() => {
const user = await methods.checkUserEmail('jondoe@nowhere.com') // a non-exist user
expect(user).toBeNull()
})
})
\ No newline at end of file
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-2';
import fileUpload from 'express-fileupload';
import helmet from 'helmet';
import compression from 'compression';
import methodOverride from 'method-override';
import dotenv from 'dotenv'
dotenv.config();
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', path.join( __dirname + '/views'));
app.set('view engine', 'pug');
// enable files upload
app.use(fileUpload({
createParentPath: true,
limits: {
fileSize: 1000000 // 1 MB max. file size
}
}));
app.use(methodOverride('_method'));
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", "https://unpkg.com/bootstrap-show-password@1.2.1/dist/bootstrap-show-password.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(config.app.sessionSecret));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(express.static(path.join(__dirname, 'public')));
app.use((req, res, next) => {
next();
});
app.use(session({
resave: true,
saveUninitialized: true,
secret: config.app.sessionSecret
}));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
// caching disabled for every route
// NOTE: Works in Firefox and Opera. Does not work in Edge
app.use(function(req, res, next) {
res.set('Cache-Control', 'no-cache, private, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0');
next();
});
require('./routes/public')(app, config, lang);
require('./routes/account')(app, config, passport, lang);
// Handle 404
app.use(function (req:any, res:any) {
res.status(404).render(lang+'/404')
})
// Handle 500 - any server error
app.use(function (err:any, req:any, res:any, next:any) {
console.error(err.stack)
res.status(500).render(lang+'/500', {
error: err
})
})
app.listen(app.get('port'), function () {
console.log('Express server listening on port ' + app.get('port'));
});
\ No newline at end of file
class Project {
ownerGitlabId:number
name:string
desc:string
id?:number
logo?:string
path?:string
constructor(ownerGitlabId:number, name:string, desc:string, id?:number, logo?:string, path?:string) {
this.ownerGitlabId = ownerGitlabId
this.name = name
this.desc = desc
this.id = id
this.logo = logo
this.path = path
}
// getter
getOwnerGitlabId() {
return this.ownerGitlabId
}
getId() {
return this.id
}
getName() {
return this.name
}
getDesc() {
return this.desc
}
getLogo() {
return this.logo
}
getPath() {
return this.path
}
// setter
setOwnerGitlabId(newOwnerGitlabId:number){
this.ownerGitlabId = newOwnerGitlabId
}
setId(newId:number) {
this.id = newId
}
setName(newName:string) {
this.name = newName
}
setDesc(newDesc:string) {
this.desc = newDesc
}
setLogo(newLogoUrl:string) {
this.logo = newLogoUrl
}
setPath(newPath:string) {
this.path = newPath
}
}
export = Project
\ No newline at end of file
import Project from "./project"
class Repo extends Project {
constructor(ownerGitlabId:number, name:string, desc:string, id?:number, logo?:string, path?:string) {
super(ownerGitlabId, name, desc, id, logo, path)
}
}
export = Repo
\ No newline at end of file
class User {
id:number
email:string
salutation:string // should be enum
title:string // should be enum
firstName:string
lastName:string
industry:string
organisation:string
speciality:string
is_m4lab_idp:number // 1 or 0
verificationStatus:number // 1 or 0 - // should be boolean
gitlabUserId?:number
constructor(id:number, email:string, salutation:string, title:string, firstName:string, lastName:string, industry:string, organisation:string,
speciality:string, is_m4lab_idp:number, verificationStatus:number, gitlabUserId?:number) {
this.id = id
this.email = email
this.salutation = salutation
this.title = title
this.firstName = firstName
this.lastName = lastName
this.industry = industry
this.organisation = organisation
this.speciality = speciality
this.is_m4lab_idp = is_m4lab_idp
this.verificationStatus = verificationStatus
this.gitlabUserId = gitlabUserId
}
// getter
getId() {
return this.id
}
getEmail() {
return this.email
}
getFullName() {
return this.firstName+' '+this.lastName
}
getIdpStatus() {
return this.is_m4lab_idp
}
getVerificationStatus() {
return this.verificationStatus
}
getGitlabUserId() {
return this.gitlabUserId
}
// setter
setEmail(email:string) {
this.email = email
}
setSalutation(salutation:string) {
this.salutation = salutation
}
setTitle(title:string) {
this.title = title
}
setFirstName(firstName:string) {
this.firstName = firstName
}
setLastName(lastName:string) {
this.lastName = lastName
}
setIndustry(industry:string) {
this.industry = industry
}
setOrganisation(organisation:string) {
this.organisation = organisation
}
setSpeciality(speciality:string) {
this.speciality = speciality
}
setM4lab_idp(m4lab_idp:number) {
this.is_m4lab_idp = m4lab_idp
}
setVerificationStatus(verificationStatus:number) {
this.verificationStatus = verificationStatus
}
setGitlabUserId(newGitlabUserId:number) {
this.gitlabUserId = newGitlabUserId
}
updateProfile(newSalutation:string, newTitle:string, newFirstname:string, newLastname:string, newEmail:string, newOrganisation:string, newIndustry:string, newSpeciality:string) {
this.salutation = newSalutation
this.title = newTitle
this.firstName = newFirstname
this.lastName = newLastname
this.email = newEmail
this.organisation = newOrganisation
this.industry = newIndustry
this.speciality = newSpeciality
}
}
export = User
\ No newline at end of file
import Project from "./project"
class Website extends Project {
constructor(ownerGitlabId:number, name:string, desc:string, id?:number, logo?:string, path?:string) {
super(ownerGitlabId, name, desc, id, logo, path)
}
}
export = Website
\ No newline at end of file
import mysql from 'mysql2'
var env = process.env.NODE_ENV || 'testing'
const config = require('./config')[env]
// ==== USER ACOOUNT DB CONNECTION ====
const userConnection = mysql.createPool({
host: config.database.host,
user: config.database.user,
password: config.database.password,
port: config.database.port,
database: config.database.dbUser,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
userConnection.query('USE '+config.database.dbUser)
// ==== PROJECT DB CONNECTION ====
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,
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
projectConnection.query('USE '+config.database.dbProject)
const connection = {
user: userConnection,
project: projectConnection
}
export = connection
\ No newline at end of file
import axios from 'axios'
import fs from 'fs'
import formData from 'form-data'
var env = process.env.NODE_ENV || 'testing'
const config = require('../config/config')[env]
var gitlab = {
getUserByEmail: async function(email:string) {
return axios({
method: 'get',
url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/users?search='+email,
headers: {
'Authorization': 'Bearer '+config.gitlab.token_readWriteProjects}
})
.then(res => res.data[0])
.catch(function(err){
console.error(err)
return null
})
},
createNewPages: async function(newPagesData:any, newLogoFile:string, template:any) {
let data = new formData()
data.append('avatar', fs.createReadStream(newLogoFile))
return axios({
method: 'post',
url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/user/'+newPagesData.getOwnerGitlabId()+
'?name='+newPagesData.getName()+'&description='+newPagesData.getDesc()+'&tag_list=website'+
'&use_custom_template=true&template_name='+template,
headers: {
'Authorization': 'Bearer '+config.gitlab.token_readWriteProjects,
...data.getHeaders()
},
data: data
})
.then(res => res.data)
.catch(function(err) {
console.error("ERR Status: "+err.response.status)
console.error("ERR Name: "+err.response.data.message.name)
console.error("ERR Path: "+err.response.data.message.path)
return err.response
})
},
updateProject: async function(updatedProjectData:any, newLogoFile:string){
let data = new formData()
if (newLogoFile) {
data.append('avatar', fs.createReadStream(newLogoFile))
}
return axios({
method: 'put',
url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/'+updatedProjectData.getId()+
'?name='+updatedProjectData.getName()+'&description='+updatedProjectData.getDesc(),
headers: {
'Authorization': 'Bearer '+config.gitlab.token_readWriteProjects,
...data.getHeaders()
},
data : data
})
//.then(res => res.data[0])
.then(res => res.data)
.catch(function(err){
console.error("ERR Status: "+err.response.status)
console.error("ERR Name: "+err.response.data.message.name)
console.error("ERR Path: "+err.response.data.message.path)
return err.response
})
},
deleteProjectById: function(projectId:number){
// https://docs.gitlab.com/ee/api/projects.html#delete-project
return axios({
method: 'delete',
url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/'+projectId,
headers: {
'Authorization': 'Bearer '+config.gitlab.token_readWriteProjects
}
})
.then(res => true)
.catch(function(err) {
console.error("ERR Status: "+err.response.status)
console.error("ERR Name: "+err.response.data.message.name)
console.error("ERR Path: "+err.response.data.message.path)
return false
})
},
getUserProjects: async function(gitlabUserId:number) {
return axios({
method: 'get',
url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/users/'+gitlabUserId+'/projects?owned=true&visibility=public',
headers: {
'Authorization': 'Bearer '+config.gitlab.token_readWriteProjects
}
})
.then(res => res.data)
.catch(function(err) {
console.error(err)
return null
})
},
getProjectById: async function(projectId:number) {
return axios({
method: 'get',
url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/'+projectId,
headers: {
'Authorization': 'Bearer '+config.gitlab.token_readWriteProjects
}
})
.then(res => res.data)
.catch(function(err) {
console.error(err)
return null
})
},
getProjectPipelineLatestStatus: async function(projectId:number) {
return axios({
method: 'get',
url: 'https://transfer.hft-stuttgart.de/gitlab/api/v4/projects/'+projectId+'/pipelines'
})
.then(res => res.data[0].status)
.catch(function(err) {
console.error(err)
return null
})
}
}
export = gitlab
\ No newline at end of file
var helpers = {
stringToArray: function (input:string){
if(input != null){
return input.split(',');
}else{
return null;
}
}
};
export = helpers;
\ No newline at end of file
import dbconn = require('../config/dbconn')
var methods = {
// ===================== user db =====================
registerNewUser: function(data:any, callback:any) {
dbconn.user.getConnection(function(err:any, thisconn){
thisconn.beginTransaction(function(err:any) { // START TRANSACTION
if (err) { throw err }
// insert profile
thisconn.query('INSERT INTO user SET ?', data.profile, function (err:any, results:any, fields:any) {
if (err) {
return thisconn.rollback(function() {
throw err
});
}
let newUserId:number = results.insertId
// set password
var credentialData:any = {
user_id: newUserId,
password: data.password
}
thisconn.query('INSERT INTO credential SET ?', credentialData, function (err:any, results:any, fields:any) {
if (err) {
return thisconn.rollback(function() {
throw err
});
}
// set default user-project-role
var projectRoleData:any = {
project_id: 1, //M4_LAB
role_id: 2, // USER
user_id: newUserId
}
thisconn.query('INSERT INTO user_project_role SET ?', projectRoleData, function (err:any, results:any, fields:any) {
if (err) {
return thisconn.rollback(function() {
throw err
});
}
// MLAB-129: INSERT verification token
let verificationData:any = {
user_id: newUserId,
token: data.verificationToken
}
thisconn.query('INSERT INTO verification SET ?', verificationData, function (err:any, results:any, fields:any) {
if (err) {
return thisconn.rollback(function() {
throw err
});
}
// COMMIT
thisconn.commit(function(err:any) {
if (err) {
return thisconn.rollback(function() {
throw err
})
}
})
})
})
});
});
});
callback(err)
})
},
getUserByEmail: async function(email:any) {
try {
let rows:any = await dbconn.user.promise().query('SELECT id, verificationStatus, salutation, title, firstname, lastname, industry, organisation, speciality, m4lab_idp FROM user WHERE email = "' +email+'"')
if (rows[0][0]) {
return rows[0][0]
}
else { return null }
} catch (err) {
console.error(err)
}
return null
},
getUserEmailById: async function(userId:number) {
try {
let rows:any = await dbconn.user.promise().query('SELECT email FROM user WHERE id = ' +userId)
if (rows[0][0]) {
return rows[0][0].email
}
else { return null }
} catch (err) {
console.error(err)
}
return null
},
checkUserEmail: async function(email:any) {
try {
let rows:any = await dbconn.user.promise().query('SELECT id, email FROM user WHERE email = "' +email+'"')
if (rows[0][0]) {
return rows[0][0]
}
else { return null }
} catch (err) {
console.error(err)
}
return null
},
getUserByToken: async function(token:any) {
try {
let rows:any = await dbconn.user.promise().query('SELECT t1.user_id, t2.email FROM userdb.credential AS t1 INNER JOIN userdb.user AS t2 ON t1.user_id = t2.id AND t1.resetPasswordToken = "'
+token+'" and resetPasswordExpires > '+Date.now())
if (rows[0][0]) {
return rows[0][0]
}
else { return null }
} catch (err) {
console.error(err)
}
return null
},
updateUserById: async function(userId:number, userData:any) {
try {
let result:any = await dbconn.user.promise().query('UPDATE user SET ? WHERE id = ' +userId, userData)
return result
} catch (err) {
console.error(err)
}
return null
},
updateCredential: async function(data:any) {
try {
let result:any = await dbconn.user.promise().query('UPDATE credential SET ? WHERE user_id = ' +data.user_id, data)
return result
} catch (err) {
console.error(err)
}
return null
},
addUserProjectRole_OBSOLETE: function(data:any, callback:any) {
dbconn.user.query('INSERT INTO user_project_role SET ?', data, function (err:any){
if (err) throw err
callback(err)
})
},
getVerificationTokenByUserId: async function(userId:number) {
try {
let rows:any = await dbconn.user.promise().query('SELECT token FROM verification WHERE user_id = "' +userId+'"')
if (rows[0][0]) {
return rows[0][0].token
}
else { return null }
} catch (err) {
console.error(err)
}
return null
},
getUserIdByVerificationToken: async function(token:any) {
try {
let rows:any = await dbconn.user.promise().query('SELECT user_id FROM verification WHERE token = "' +token+'"')
if (rows[0][0]) {
return rows[0][0].user_id
}
else {
return null
}
} catch (err) {
console.error(err)
}
return null
},
verifyUserAccount: function(userData:any, callback:any) {
dbconn.user.getConnection(function(err:any, thisconn){
thisconn.beginTransaction(function(err:any) { // START TRANSACTION
if (err) { throw err }
// update user status
thisconn.query('UPDATE user SET ? WHERE id =' +userData.id, userData, function (err:any, rows:any, fields:any) {
if (err) {
return thisconn.rollback(function() { throw err })
}
// delete verification token
thisconn.query('DELETE FROM verification WHERE user_id = '+userData.id, function (err:any, rows:any, fields:any) {
if (err) {
return thisconn.rollback(function() { throw err })
}
// COMMIT
thisconn.commit(function(err:any) {
if (err) {
return thisconn.rollback(function() { throw err })
}
})
})
})
})
callback(err)
})
},
/* ===== GitLab ===== */
getGitlabId: async function(userId:number) {
try {
let rows:any = await dbconn.user.promise().query('SELECT gu.gitlab_userId FROM user_gitlab gu, user u WHERE u.id = "' +userId+'" and gu.user_id = u.id')
if (rows[0][0]) {
return rows[0][0].gitlab_userId
} else {
return null
}
}
catch(err) {
console.error(err)
return err
}
},
addGitlabUser: function(data:any, callback:any){
dbconn.user.query('INSERT INTO user_gitlab SET ?', data, function (err:any) {
if (err) throw err
callback(err)
})
}
};
export = methods
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node'
}
This diff is collapsed.
......@@ -16,10 +16,13 @@
"url": "https://transfer.hft-stuttgart.de/gitlab/m4lab_tv1/user-account.git"
},
"scripts": {
"start": "nodemon app.ts",
"build": "tsc -build",
"clean": "tsc -build --clean",
"test": "jest"
"start:dev": "nodemon ./src/app.ts",
"start": "nodemon ./built/app.js",
"test": "jest",
"clean-code": "ts-standard --fix",
"check-types": "tsc --noEmit",
"clean": "rm -rf ./built",
"build": "babel src --out-dir built --extensions .ts --copy-files"
},
"dependencies": {
"async": "^3.1.0",
......@@ -28,7 +31,6 @@
"body-parser": "^1.19.0",
"compression": "^1.7.4",
"cookie-parser": "1.4.3",
"dotenv": "^9.0.2",
"express": "^4.17.1",
"express-fileupload": "^1.1.6",
"express-flash-2": "^1.0.1",
......@@ -36,7 +38,6 @@
"form-data": "^3.0.0",
"fs": "0.0.1-security",
"helmet": "^4.6.0",
"jest": "^26.5.0",
"method-override": "^3.0.0",
"morgan": "^1.9.1",
"mysql2": "^2.2.5",
......@@ -47,6 +48,10 @@
"pug": "^3.0.2"
},
"devDependencies": {
"@babel/cli": "^7.18.6",
"@babel/core": "^7.18.6",
"@babel/preset-env": "^7.18.6",
"@babel/preset-typescript": "^7.18.6",
"@types/async": "^3.2.6",
"@types/bcryptjs": "^2.4.2",
"@types/compression": "^1.7.0",
......@@ -55,7 +60,7 @@
"@types/express-fileupload": "^1.1.6",
"@types/express-flash-2": "^1.0.6",
"@types/express-session": "^1.17.0",
"@types/jest": "^26.0.23",
"@types/jest": "^28.1.3",
"@types/method-override": "^0.0.31",
"@types/morgan": "^1.9.2",
"@types/mysql": "^2.15.18",
......@@ -63,9 +68,15 @@
"@types/nodemailer": "^6.4.1",
"@types/passport": "^1.0.6",
"@types/passport-strategy": "^0.2.35",
"@types/supertest": "^2.0.12",
"@types/xml2js": "^0.4.8",
"babel-preset-minify": "^0.5.2",
"jest": "^28.1.1",
"nodemon": "^2.0.1",
"supertest": "^6.2.3",
"ts-jest": "^28.0.5",
"ts-node": "^9.1.1",
"ts-standard": "^11.0.0",
"typescript": "^4.2.4"
},
"engines": {
......
// password requirement
function checkPasswordReq(pwd) {
if (pwd.length < 8) {
isBest = false;
} else {
isBest = true;
}
return isBest
}
\ No newline at end of file
var menu = [{'name':'Informationen', 'combos':[{'name':'Projekte', 'link':'/project'}, {'name':'Über das M4_LAB', 'link':'/projectoverview?projectID=1'}], 'type':'dropdown', 'link':'#'},{'name':'Zusammenarbeit', 'combos':[{'name':'Mailinglisten', 'link':'/mailinglists'},{'name':'Videokonferenzen', 'link':'/videoconference.html'},/* {'name':'...', 'link':'#'}*/], 'type':'dropdown', 'link':'#'},{'name':'Events', 'combos':[{'name':'Veranstaltungen der HfT', 'link':'http://www.hft-stuttgart.de/Aktuell/Veranstaltungen/'}/*,{'name':'...', 'link':'#'}*/], 'type':'dropdown', 'link':'#'},/*{'name':'Bürgerbeteiligung', 'combos':[{'name':'...', 'link':'#'}, {'name':'...', 'link':'#'}], 'type':'dropdown', 'link':'#'},*/{'name':'Logout', 'combos':[], 'type':'logoutbutton', 'link':'/logout'}];
var hft_links = [{'url':'http://www.hft-stuttgart.de/Forschung/M4-Lab/Team/index.html/de', 'name':'Kontakt'},{'url':'http://www.hft-stuttgart.de/Hochschule/Impressum.html/de', 'name':'Impressum'},{'url':'http://www.hft-stuttgart.de/Einrichtungen/Datenschutz/Datenschutz-Homepage', 'name':'Datenschutz'}]
var socialmedias = [{'url':'https://twitter.com/InnolabM4', 'name': 'fa-twitter'}, {'url':'https://www.facebook.com/HfTStuttgart/', 'name': 'fa-facebook-square'}, {'url':'https://www.instagram.com/m4_lab/', 'name': 'fa-instagram'}, {'url':'https://de.linkedin.com/school/hochschule-f%C3%BCr-technik-stuttgart-%E2%80%93-university-of-applied-sciences/', 'name': 'fa-linkedin'}, {'url':'https://www.youtube.com/channel/UCi0_JfF2qMZbOhOnNH5PyHA', 'name': 'fa-youtube'}];
var footer_images = [/*{'src':'/images/demo/bbf_logo.png', 'alt':'BMBF'},*/ {'src':'/images/demo/Innovative_Hochschule_Initiative_BMBF_GWK_RGB.jpg', 'alt':'Innovative Hochschule'}]
function prependChild(parent,child){
parent.insertBefore(child, parent.childNodes[0]);
}
function userAuthenticated(){
let params = new URLSearchParams(window.location.search);
if(params.get('isAuthenticatedUser')){
return true;
}else if(document.getElementById('loginswitch')){ //relikt login via OAuth
if(document.getElementById('loginswitch').getAttribute('authenticated') == '1'){
return true;
}
}else{
return false;
}
}
function readCookie(cname) {
var name = cname + "=";
var decodedCookie = decodeURIComponent(document.cookie);
var ca = decodedCookie.split(';');
for(var i = 0; i <ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
function sendRequest(URL){
console.log(document.cookie);
let xhr = new XMLHttpRequest();
xhr.open("POST", URL, true);
let token = readCookie("XSRF-TOKEN");
//Send the proper header information along with the request
xhr.setRequestHeader('X-CSRF-TOKEN', token);
xhr.send();
}
/* function head()
* creates header and prepends it to the documents body
*/
function head(){
let headerdiv = document.createElement('div');
let alertdiv = document.createElement('div');
headerdiv.classList.add("wrapper","row1");
let navheader = document.createElement('header');
navheader.id = "header";
navheader.classList.add("clear");
let alertbutton = document.createElement('button');
alertbutton.type = "button";
alertbutton.classList.add("close");
alertbutton.setAttribute("data-dismiss", "alert");
alertbutton.innerHTML = "&times;";
alertdiv.innerHTML="<strong>Disclaimer</strong> This website is under construction and in prototype-phase. It is not for public use."
prependChild(alertdiv, alertbutton);
alertdiv.classList.add('alert','alert-danger', 'alert-dismissible', 'fade','show', 'text-center');
//alertdiv.style = "text-align:center;";
navheader.appendChild(alertdiv);
let navbar = document.createElement('nav');
navbar.classList.add("navbar", "navbar-default");
let fluiddiv = document.createElement('div');
fluiddiv.classList.add("container-fluid");
let navbardiv = document.createElement('div');
navbardiv.classList.add("navbar-header");
let navelements = document.createElement('ul');
navelements.id="navelemente";
let logos = document.createElement('li');
let link_m4lab = document.createElement('a');
link_m4lab.href = "/";
link_m4lab.innerHTML = "<img src='/images/demo/m4lab_logo.jpg' alt='Logo Innovationslabor M4_LAB'>";
logos.appendChild(link_m4lab);
navelements.appendChild(logos);
for(let j = 0; j<menu.length; j++){
let headitem = document.createElement('li');
let itemtype = menu[j].type;
headitem.classList.add("nav-item")
let headlink = document.createElement('a');
headlink.href=menu[j].link;
headlink.id="navbarDropdown" + j;
headlink.classList.add('nav-link');
headlink.setAttribute("role", "button");
if(itemtype=='dropdown'){
headitem.classList.add("dropdown");
headlink.classList.add('dropdown-toggle');
headlink.setAttribute("data-toggle", "dropdown");
headlink.setAttribute("aria-haspopup", "true");
headlink.setAttribute("aria-expanded", "false");
}
headlink.innerHTML=menu[j].name;
if(itemtype=='dropdown'){
let combodiv = document.createElement('div');
combodiv.id=headlink.id+"_par";
combodiv.setAttribute("aria-labelledby",headlink.id);
combodiv.classList.add("dropdown-menu");
for(let k = 0; k< menu[j].combos.length; k++){
let combolink = document.createElement('a');
combolink.classList.add("dropdown-item");
if(userAuthenticated() || typeof user !== 'undefined'){ //either logged in the old way or logged in using SAML
if(menu[j].combos[k].link.includes('?')){
combolink.href = menu[j].combos[k].link + "&isAuthenticatedUser=true";
}else{
combolink.href = menu[j].combos[k].link + "?isAuthenticatedUser=true";
}
}else{
combolink.href = menu[j].combos[k].link;
}
combolink.innerHTML = menu[j].combos[k].name;
combodiv.appendChild(combolink);
}
headitem.appendChild(combodiv);
}else if(itemtype=='logoutbutton'){
/* if(userAuthenticated()){
headlink.innerHTML="Account";
headlink.href="/account/";
} */
headlink.innerHTML="Logout";
headlink.href="/logout";
headlink.classList.remove("nav-link");
headlink.classList.add("btn");
headlink.classList.add("btn-outline-danger");
}
headitem.appendChild(headlink);
navelements.appendChild(headitem);
}
/* let searchitem = document.createElement('li');
searchitem.classList.add("nav-item");
let searchinput = document.createElement('input');
searchinput.value='Suche...'
searchinput.type="text";
searchinput.classList.add("nav-item-suchfeld");
searchinput.setAttribute('onFocus', "this.value=(this.value=='search...')? '' : this.value");
searchitem.appendChild(searchinput);
let magnifier = document.createElement('input');
magnifier.type="image"
magnifier.src="/images/Lupe_grau.png";
magnifier.width="25";
magnifier.height="25";
magnifier.alt="";
magnifier.id="sf_submit";
magnifier.value="search";
searchitem.appendChild(magnifier);
navelements.appendChild(searchitem);*/
navbardiv.appendChild(navelements);
fluiddiv.appendChild(navbardiv);
navbar.appendChild(fluiddiv);
navheader.appendChild(navbar);
headerdiv.appendChild(navheader);
prependChild(document.body, headerdiv);
};
/* function foot()
* creates footer and appends it to the documents body
*/
function foot(){
let footerdiv = document.createElement('div');
footerdiv.id="homepage";
footerdiv.classList.add("last", "clear");
footerdiv.innerHTML = "<hr>";
let containerdiv = document.createElement('div');
containerdiv.classList.add('flex-container');
let hftlink = document.createElement('a');
hftlink.classList.add("col-md-3");
hftlink.setAttribute('style','flex-basis: 400px;');
hftlink.href="https://www.hft-stuttgart.de";
let hftimage = document.createElement('img');
hftimage.src="/images/demo/hft_logo.jpg";
hftimage.alt="Logo der Hochschule für Technik Stuttgart";
hftimage.height= '75';
hftlink.appendChild(hftimage);
containerdiv.appendChild(hftlink);
let contactdiv = document.createElement('div');
contactdiv.classList.add("col-md-3", "footer-unten")
contactdiv.setAttribute('style',"flex-basis:400px");
contactdiv.innerHTML="Hochschule für Technik Stuttgart";
let rowdiv = document.createElement('div');
rowdiv.classList.add("row");
for(let i = 0; i<hft_links.length; i++){
let coldiv = document.createElement('div');
coldiv.classList.add("contactrow", "footer-unten");
let collink = document.createElement('a');
collink.innerHTML = hft_links[i].name;
collink.classList.add("contact-lower")
collink.href = hft_links[i].url;
coldiv.appendChild(collink)
rowdiv.appendChild(coldiv);
}
contactdiv.appendChild(rowdiv);
containerdiv.appendChild(contactdiv);
let socialdiv = document.createElement('div');
socialdiv.classList.add("col-md-3");
socialdiv.setAttribute('style','flex-basis: 400px;');
let socialrow = document.createElement('div');
socialrow.id="socialmediabuttons";
for(let j = 0; j< socialmedias.length; j++){
let sociallink = document.createElement('a');
sociallink.href = socialmedias[j].url;
let socialcontent = document.createElement('i');
socialcontent.classList.add("fab", socialmedias[j].name);
sociallink.appendChild(socialcontent);
socialrow.appendChild(sociallink);
socialrow.innerHTML+="&nbsp;";
}
socialdiv.appendChild(socialrow);
containerdiv.appendChild(socialdiv);
let imagediv = document.createElement('div');
imagediv.classList.add("col-md-3");
imagediv.setAttribute("style", "flex-basis:400px;");
for (let k = 0; k< footer_images.length; k++){
let image = document.createElement('img');
image.src = footer_images[k].src;
image.width="300";
image.height= "73";
image.alt = footer_images[k].alt;
imagediv.appendChild(image);
}
containerdiv.appendChild(imagediv);
footerdiv.appendChild(containerdiv);
document.body.appendChild(footerdiv);
};
head();
foot();
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment