Compare commits
	
		
			5 Commits
		
	
	
		
			f52897fd4d
			...
			af896a6688
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| af896a6688 | |||
| 347979bb10 | |||
| ddfdfc3092 | |||
| 56cbebb36b | |||
| e307ff97ac | 
							
								
								
									
										139
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										139
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -21,8 +21,11 @@
 | 
			
		||||
        "eta": "^2.0.1",
 | 
			
		||||
        "express": "^4.18.2",
 | 
			
		||||
        "express-fileupload": "^1.4.0",
 | 
			
		||||
        "express-session": "^1.17.3",
 | 
			
		||||
        "jquery": "^3.6.4",
 | 
			
		||||
        "lodash": "^4.17.21",
 | 
			
		||||
        "passport": "^0.6.0",
 | 
			
		||||
        "passport-local": "^1.0.0",
 | 
			
		||||
        "signale": "^1.4.0",
 | 
			
		||||
        "tsparticles-confetti": "^2.9.3"
 | 
			
		||||
      },
 | 
			
		||||
@@ -30,7 +33,10 @@
 | 
			
		||||
        "@loancrate/prisma-schema-parser": "^2.0.0",
 | 
			
		||||
        "@types/express": "^4.17.17",
 | 
			
		||||
        "@types/express-fileupload": "^1.4.1",
 | 
			
		||||
        "@types/express-session": "^1.17.7",
 | 
			
		||||
        "@types/lodash": "^4.14.194",
 | 
			
		||||
        "@types/passport": "^1.0.12",
 | 
			
		||||
        "@types/passport-local": "^1.0.35",
 | 
			
		||||
        "@types/signale": "^1.4.4",
 | 
			
		||||
        "eslint": "^8.39.0",
 | 
			
		||||
        "eslint-config-prettier": "^8.8.0",
 | 
			
		||||
@@ -832,6 +838,15 @@
 | 
			
		||||
        "@types/send": "*"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@types/express-session": {
 | 
			
		||||
      "version": "1.17.7",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@types/express-session/-/express-session-1.17.7.tgz",
 | 
			
		||||
      "integrity": "sha512-L25080PBYoRLu472HY/HNCxaXY8AaGgqGC8/p/8+BYMhG0RDOLQ1wpXOpAzr4Gi5TGozTKyJv5BVODM5UNyVMw==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@types/express": "*"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@types/lodash": {
 | 
			
		||||
      "version": "4.14.194",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.194.tgz",
 | 
			
		||||
@@ -868,6 +883,36 @@
 | 
			
		||||
      "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
 | 
			
		||||
      "dev": true
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@types/passport": {
 | 
			
		||||
      "version": "1.0.12",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@types/passport/-/passport-1.0.12.tgz",
 | 
			
		||||
      "integrity": "sha512-QFdJ2TiAEoXfEQSNDISJR1Tm51I78CymqcBa8imbjo6dNNu+l2huDxxbDEIoFIwOSKMkOfHEikyDuZ38WwWsmw==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@types/express": "*"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@types/passport-local": {
 | 
			
		||||
      "version": "1.0.35",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@types/passport-local/-/passport-local-1.0.35.tgz",
 | 
			
		||||
      "integrity": "sha512-K4eLTJ8R0yYW8TvCqkjB0pTKoqfUSdl5PfZdidTjV2ETV3604fQxtY6BHKjQWAx50WUS0lqzBvKv3LoI1ZBPeA==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@types/express": "*",
 | 
			
		||||
        "@types/passport": "*",
 | 
			
		||||
        "@types/passport-strategy": "*"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@types/passport-strategy": {
 | 
			
		||||
      "version": "0.2.35",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@types/passport-strategy/-/passport-strategy-0.2.35.tgz",
 | 
			
		||||
      "integrity": "sha512-o5D19Jy2XPFoX2rKApykY15et3Apgax00RRLf0RUotPDUsYrQa7x4howLYr9El2mlUApHmCMv5CZ1IXqKFQ2+g==",
 | 
			
		||||
      "dev": true,
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "@types/express": "*",
 | 
			
		||||
        "@types/passport": "*"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/@types/qs": {
 | 
			
		||||
      "version": "6.9.7",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz",
 | 
			
		||||
@@ -2337,6 +2382,32 @@
 | 
			
		||||
        "node": ">=12.0.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/express-session": {
 | 
			
		||||
      "version": "1.17.3",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.3.tgz",
 | 
			
		||||
      "integrity": "sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "cookie": "0.4.2",
 | 
			
		||||
        "cookie-signature": "1.0.6",
 | 
			
		||||
        "debug": "2.6.9",
 | 
			
		||||
        "depd": "~2.0.0",
 | 
			
		||||
        "on-headers": "~1.0.2",
 | 
			
		||||
        "parseurl": "~1.3.3",
 | 
			
		||||
        "safe-buffer": "5.2.1",
 | 
			
		||||
        "uid-safe": "~2.1.5"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">= 0.8.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/express-session/node_modules/cookie": {
 | 
			
		||||
      "version": "0.4.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz",
 | 
			
		||||
      "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">= 0.6"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/express/node_modules/body-parser": {
 | 
			
		||||
      "version": "1.20.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz",
 | 
			
		||||
@@ -4211,6 +4282,14 @@
 | 
			
		||||
        "node": ">= 0.8"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/on-headers": {
 | 
			
		||||
      "version": "1.0.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz",
 | 
			
		||||
      "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">= 0.8"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/once": {
 | 
			
		||||
      "version": "1.4.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
 | 
			
		||||
@@ -4422,6 +4501,42 @@
 | 
			
		||||
        "node": ">= 0.8"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/passport": {
 | 
			
		||||
      "version": "0.6.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/passport/-/passport-0.6.0.tgz",
 | 
			
		||||
      "integrity": "sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "passport-strategy": "1.x.x",
 | 
			
		||||
        "pause": "0.0.1",
 | 
			
		||||
        "utils-merge": "^1.0.1"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">= 0.4.0"
 | 
			
		||||
      },
 | 
			
		||||
      "funding": {
 | 
			
		||||
        "type": "github",
 | 
			
		||||
        "url": "https://github.com/sponsors/jaredhanson"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/passport-local": {
 | 
			
		||||
      "version": "1.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-9wCE6qKznvf9mQYYbgJ3sVOHmCWoUNMVFoZzNoznmISbhnNNPhN9xfY3sLmScHMetEJeoY7CXwfhCe7argfQow==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "passport-strategy": "1.x.x"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">= 0.4.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/passport-strategy": {
 | 
			
		||||
      "version": "1.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA==",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">= 0.4.0"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/path-exists": {
 | 
			
		||||
      "version": "4.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
 | 
			
		||||
@@ -4469,6 +4584,11 @@
 | 
			
		||||
        "node": ">=8"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/pause": {
 | 
			
		||||
      "version": "0.0.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
 | 
			
		||||
      "integrity": "sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg=="
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/picomatch": {
 | 
			
		||||
      "version": "2.3.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
 | 
			
		||||
@@ -5116,6 +5236,14 @@
 | 
			
		||||
        "node": ">=8"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/random-bytes": {
 | 
			
		||||
      "version": "1.0.0",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz",
 | 
			
		||||
      "integrity": "sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==",
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">= 0.8"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/range-parser": {
 | 
			
		||||
      "version": "1.2.1",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
 | 
			
		||||
@@ -6369,6 +6497,17 @@
 | 
			
		||||
        "node": ">=12.20"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/uid-safe": {
 | 
			
		||||
      "version": "2.1.5",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz",
 | 
			
		||||
      "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==",
 | 
			
		||||
      "dependencies": {
 | 
			
		||||
        "random-bytes": "~1.0.0"
 | 
			
		||||
      },
 | 
			
		||||
      "engines": {
 | 
			
		||||
        "node": ">= 0.8"
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    "node_modules/unbox-primitive": {
 | 
			
		||||
      "version": "1.0.2",
 | 
			
		||||
      "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
 | 
			
		||||
 
 | 
			
		||||
@@ -29,8 +29,11 @@
 | 
			
		||||
    "eta": "^2.0.1",
 | 
			
		||||
    "express": "^4.18.2",
 | 
			
		||||
    "express-fileupload": "^1.4.0",
 | 
			
		||||
    "express-session": "^1.17.3",
 | 
			
		||||
    "jquery": "^3.6.4",
 | 
			
		||||
    "lodash": "^4.17.21",
 | 
			
		||||
    "passport": "^0.6.0",
 | 
			
		||||
    "passport-local": "^1.0.0",
 | 
			
		||||
    "signale": "^1.4.0",
 | 
			
		||||
    "tsparticles-confetti": "^2.9.3"
 | 
			
		||||
  },
 | 
			
		||||
@@ -38,7 +41,10 @@
 | 
			
		||||
    "@loancrate/prisma-schema-parser": "^2.0.0",
 | 
			
		||||
    "@types/express": "^4.17.17",
 | 
			
		||||
    "@types/express-fileupload": "^1.4.1",
 | 
			
		||||
    "@types/express-session": "^1.17.7",
 | 
			
		||||
    "@types/lodash": "^4.14.194",
 | 
			
		||||
    "@types/passport": "^1.0.12",
 | 
			
		||||
    "@types/passport-local": "^1.0.35",
 | 
			
		||||
    "@types/signale": "^1.4.4",
 | 
			
		||||
    "eslint": "^8.39.0",
 | 
			
		||||
    "eslint-config-prettier": "^8.8.0",
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,18 @@
 | 
			
		||||
		<div class="col-9"></div>
 | 
			
		||||
		<div class="col-3 sidePanel ps-4 text-black">
 | 
			
		||||
			<h1>Log into AssetFlow</h1>
 | 
			
		||||
			<form action="/auth/login" method="post">
 | 
			
		||||
				<div class="mb-3">
 | 
			
		||||
					<label for="userName" class="form-label">Username</label>
 | 
			
		||||
					<input name="username" type="text" class="form-control" id="userName" aria-describedby="userNameHelp" />
 | 
			
		||||
					<!-- <div id="userNameHelp" class="form-text">We'll never share your email with anyone else.</div> -->
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="mb-3">
 | 
			
		||||
					<label for="userPassword" class="form-label">Password</label>
 | 
			
		||||
					<input name="password" type="password" class="form-control" id="userPassword" />
 | 
			
		||||
				</div>
 | 
			
		||||
				<button type="submit" class="btn btn-primary">Submit</button>
 | 
			
		||||
			</form>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
	<%~ E.includeFile("../partials/foot.eta.html") %>
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										53
									
								
								src/index.ts
									
									
									
									
									
								
							
							
						
						
									
										53
									
								
								src/index.ts
									
									
									
									
									
								
							@@ -5,6 +5,8 @@ import fileUpload from 'express-fileupload';
 | 
			
		||||
import { PrismaClient } from '@prisma/client';
 | 
			
		||||
import * as eta from 'eta';
 | 
			
		||||
import bodyParser from 'body-parser';
 | 
			
		||||
import session from 'express-session';
 | 
			
		||||
import passport from 'passport';
 | 
			
		||||
 | 
			
		||||
// Sentry
 | 
			
		||||
import * as Sentry from '@sentry/node';
 | 
			
		||||
@@ -28,6 +30,7 @@ export const log = {
 | 
			
		||||
	core: coreLogger,
 | 
			
		||||
	db: coreLogger.scope('DB'),
 | 
			
		||||
	web: coreLogger.scope('WEB'),
 | 
			
		||||
	auth: coreLogger.scope('AUTH'),
 | 
			
		||||
	helper: coreLogger.scope('HELPER')
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@@ -37,9 +40,22 @@ export const config = new ConfigHandler(__path + '/config.json', {
 | 
			
		||||
	http_listen_address: '127.0.0.1',
 | 
			
		||||
	http_port: 3000,
 | 
			
		||||
	sentry_dsn: 'https://ID@sentry.example.com/PROJECTID',
 | 
			
		||||
	debug: false
 | 
			
		||||
	debug: false,
 | 
			
		||||
	auth: {
 | 
			
		||||
		local: {
 | 
			
		||||
			active: true,
 | 
			
		||||
			users: {
 | 
			
		||||
				user: 'password',
 | 
			
		||||
				user1: 'password'
 | 
			
		||||
			}
 | 
			
		||||
		},
 | 
			
		||||
		oidc: {
 | 
			
		||||
			active: false
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// TODO: Add errorhandling with some sort of message.
 | 
			
		||||
export const prisma = new PrismaClient({
 | 
			
		||||
	datasources: {
 | 
			
		||||
		db: {
 | 
			
		||||
@@ -67,16 +83,16 @@ Sentry.init({
 | 
			
		||||
	environment: config.global.debug ? 'development' : 'production'
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
app.locals.versionRevLong = require('child_process')
 | 
			
		||||
.execSync('git rev-parse HEAD')
 | 
			
		||||
.toString().trim()
 | 
			
		||||
app.locals.versionRev = require('child_process')
 | 
			
		||||
.execSync('git rev-parse --short HEAD')
 | 
			
		||||
.toString().trim()
 | 
			
		||||
app.locals.versionRevLatest = require('child_process')
 | 
			
		||||
.execSync('git ls-remote --refs -q')
 | 
			
		||||
.toString().trim().split("\t")[0]
 | 
			
		||||
log.core.info(`Running revision ${app.locals.versionRevLong} (${app.locals.versionRevLatest} latest)`);
 | 
			
		||||
// TODO: Version check need to be rewritten.
 | 
			
		||||
app.locals.versionRevLong = require('child_process').execSync('git rev-parse HEAD').toString().trim();
 | 
			
		||||
app.locals.versionRev = require('child_process').execSync('git rev-parse --short HEAD').toString().trim();
 | 
			
		||||
app.locals.versionRevLatest = require('child_process').execSync('git ls-remote --refs -q').toString().trim().split('\t')[0];
 | 
			
		||||
 | 
			
		||||
if (app.locals.versionRevLong === app.locals.versionRevLatest) {
 | 
			
		||||
	log.core.info(`Running Latest Version (${app.locals.versionRevLong})`);
 | 
			
		||||
} else {
 | 
			
		||||
	log.core.info(`Running Version: ${app.locals.versionRevLong} (Latest: ${app.locals.versionRevLatest})`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// RequestHandler creates a separate execution context using domains, so that every
 | 
			
		||||
// transaction/span/breadcrumb is attached to its own Hub instance
 | 
			
		||||
@@ -93,14 +109,23 @@ app.use(bodyParser.urlencoded({ extended: false }));
 | 
			
		||||
// Using bodyParser to parse JSON bodies into JS objects
 | 
			
		||||
app.use(bodyParser.json());
 | 
			
		||||
 | 
			
		||||
// Session store
 | 
			
		||||
// TODO: Move secret to config -> Autogenerate.
 | 
			
		||||
app.use(
 | 
			
		||||
	session({
 | 
			
		||||
		secret: 'keyboard cat',
 | 
			
		||||
		resave: false,
 | 
			
		||||
		saveUninitialized: false,
 | 
			
		||||
		cookie: { secure: false }
 | 
			
		||||
	})
 | 
			
		||||
);
 | 
			
		||||
app.use(passport.authenticate('session'));
 | 
			
		||||
 | 
			
		||||
app.use(fileUpload());
 | 
			
		||||
app.use(express.static(__path + '/static'));
 | 
			
		||||
 | 
			
		||||
app.use(routes);
 | 
			
		||||
 | 
			
		||||
// The error handler must be before any other error middleware and after all controllers
 | 
			
		||||
app.use(Sentry.Handlers.errorHandler());
 | 
			
		||||
 | 
			
		||||
app.listen(config.global.http_port, config.global.http_listen_address, () => {
 | 
			
		||||
	log.web.info(`Listening at http://${config.global.http_listen_address}:${config.global.http_port}`);
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										23
									
								
								src/middleware/auth.mw.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/middleware/auth.mw.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
			
		||||
/*
 | 
			
		||||
function checkAuthentication(req: any, res: any, next: Function) {
 | 
			
		||||
	if (req.isAuthenticated()) {
 | 
			
		||||
		//req.isAuthenticated() will return true if user is logged in
 | 
			
		||||
		next();
 | 
			
		||||
	} else {
 | 
			
		||||
		res.redirect('/auth/login');
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const checkIsInRole = (...roles) => (req, res, next) => {
 | 
			
		||||
	if (!req.user) {
 | 
			
		||||
		return res.redirect('/login')
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	const hasRole = roles.find(role => req.user.role === role)
 | 
			
		||||
	if (!hasRole) {
 | 
			
		||||
		return res.redirect('/login')
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return next()
 | 
			
		||||
}
 | 
			
		||||
*/
 | 
			
		||||
@@ -1,4 +1,5 @@
 | 
			
		||||
import express from 'express';
 | 
			
		||||
import passport from 'passport';
 | 
			
		||||
 | 
			
		||||
// Route imports
 | 
			
		||||
import testRoute from './test.js';
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										96
									
								
								src/routes/auth/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								src/routes/auth/index.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,96 @@
 | 
			
		||||
import passport from 'passport';
 | 
			
		||||
import { Strategy as LocalStrategy } from 'passport-local';
 | 
			
		||||
import express, { Request, Response } from 'express';
 | 
			
		||||
import { prisma, __path, log, config, app } from '../../index.js';
 | 
			
		||||
 | 
			
		||||
/* Configure password authentication strategy.
 | 
			
		||||
 *
 | 
			
		||||
 * The `LocalStrategy` authenticates users by verifying a username and password.
 | 
			
		||||
 * The strategy parses the username and password from the request and calls the
 | 
			
		||||
 * `verify` function.
 | 
			
		||||
 *
 | 
			
		||||
 * The `verify` function queries the database for the user record and verifies
 | 
			
		||||
 * the password by hashing the password supplied by the user and comparing it to
 | 
			
		||||
 * the hashed password stored in the database.  If the comparison succeeds, the
 | 
			
		||||
 * user is authenticated; otherwise, not.
 | 
			
		||||
 */
 | 
			
		||||
passport.use(
 | 
			
		||||
	new LocalStrategy(function verify(username, password, cb) {
 | 
			
		||||
		//log.auth.debug('LocalStrategy:', username, password);
 | 
			
		||||
 | 
			
		||||
		for (const [user, pass] of Object.entries(config.global.auth.local.users)) {
 | 
			
		||||
			//log.auth.debug('Loop(REQ):', username, password);
 | 
			
		||||
			//log.auth.debug('Loop(CFG):', user, pass);
 | 
			
		||||
 | 
			
		||||
			if (user === username && pass === password) {
 | 
			
		||||
				log.auth.debug('LocalStrategy: success');
 | 
			
		||||
				return cb(null, { username: username }); // This is the user object.
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		log.auth.debug('LocalStrategy: failed');
 | 
			
		||||
		return cb(null, false, { message: 'Incorrect username or password.' });
 | 
			
		||||
	})
 | 
			
		||||
	/*
 | 
			
		||||
	1. If the user not found in DB,
 | 
			
		||||
	done (null, false)
 | 
			
		||||
	
 | 
			
		||||
	2. If the user found in DB, but password does not match, 
 | 
			
		||||
	done (null, false)
 | 
			
		||||
	
 | 
			
		||||
	3. If user found in DB and password match, 
 | 
			
		||||
	done (null, {authenticated_user})
 | 
			
		||||
	*/
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
/* Configure session management.
 | 
			
		||||
 *
 | 
			
		||||
 * When a login session is established, information about the user will be
 | 
			
		||||
 * stored in the session.  This information is supplied by the `serializeUser`
 | 
			
		||||
 * function, which is yielding the user ID and username.
 | 
			
		||||
 *
 | 
			
		||||
 * As the user interacts with the app, subsequent requests will be authenticated
 | 
			
		||||
 * by verifying the session.  The same user information that was serialized at
 | 
			
		||||
 * session establishment will be restored when the session is authenticated by
 | 
			
		||||
 * the `deserializeUser` function.
 | 
			
		||||
 *
 | 
			
		||||
 */
 | 
			
		||||
passport.serializeUser(function (user: any, cb) {
 | 
			
		||||
	process.nextTick(function () {
 | 
			
		||||
		log.auth.debug('Called seriealizeUser');
 | 
			
		||||
		log.auth.debug('user:', user);
 | 
			
		||||
		return cb(null, {
 | 
			
		||||
			username: user.username
 | 
			
		||||
		});
 | 
			
		||||
	});
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
passport.deserializeUser(function (user, cb) {
 | 
			
		||||
	process.nextTick(function () {
 | 
			
		||||
		log.auth.debug('Called deseriealizeUser');
 | 
			
		||||
		return cb(null, user);
 | 
			
		||||
	});
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// Route imports
 | 
			
		||||
import testRoute from './test.js';
 | 
			
		||||
import loginRoute from './login.js';
 | 
			
		||||
//import logoutRoute from './login.js'
 | 
			
		||||
 | 
			
		||||
// Router base is '/auth'
 | 
			
		||||
const Router = express.Router({ strict: false });
 | 
			
		||||
 | 
			
		||||
Router.route('/login').get(loginRoute.get);
 | 
			
		||||
Router.route('/login').post(passport.authenticate('local', { successRedirect: '/', failureRedirect: '/auth/login?failed' }));
 | 
			
		||||
 | 
			
		||||
Router.route('/test').get(checkAuthentication, testRoute.get);
 | 
			
		||||
 | 
			
		||||
export default Router;
 | 
			
		||||
 | 
			
		||||
function checkAuthentication(req: Request, res: Response, next: Function) {
 | 
			
		||||
	if (req.isAuthenticated()) {
 | 
			
		||||
		//req.isAuthenticated() will return true if user is logged in
 | 
			
		||||
		next();
 | 
			
		||||
	} else {
 | 
			
		||||
		res.redirect('/auth/login');
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -1,5 +1,7 @@
 | 
			
		||||
import passport from 'passport';
 | 
			
		||||
 | 
			
		||||
import express, { Request, Response } from 'express';
 | 
			
		||||
import { prisma, __path } from '../../../index.js';
 | 
			
		||||
import { prisma, __path, log } from '../../index.js';
 | 
			
		||||
 | 
			
		||||
function get(req: Request, res: Response) {
 | 
			
		||||
	res.render(__path + '/src/frontend/auth/login.eta.html'); //, { items: items });
 | 
			
		||||
							
								
								
									
										7
									
								
								src/routes/auth/test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								src/routes/auth/test.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,7 @@
 | 
			
		||||
import express, { Request, Response } from 'express';
 | 
			
		||||
 | 
			
		||||
function get(req: Request, res: Response) {
 | 
			
		||||
	res.status(200).send('Auth Test Successful!');
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export default { get };
 | 
			
		||||
@@ -7,7 +7,6 @@ import jsonImportRoute from './import/jsonImport.js';
 | 
			
		||||
import categoryManager from './categoryManager.js';
 | 
			
		||||
import storageManager from './storageManager.js';
 | 
			
		||||
import startpageRoute from './startpage.js';
 | 
			
		||||
import demoLoginRoute from './demo.js'
 | 
			
		||||
 | 
			
		||||
// Router base is '/manage'
 | 
			
		||||
const Router = express.Router({ strict: false });
 | 
			
		||||
@@ -17,7 +16,6 @@ Router.route('/categories').get(categoryManager.get);
 | 
			
		||||
Router.route('/storages').get(storageManager.get);
 | 
			
		||||
Router.route('/import/csv').get(csvImportRoute.get).post(csvImportRoute.post);
 | 
			
		||||
Router.route('/import/json').get(jsonImportRoute.get).post(jsonImportRoute.post);
 | 
			
		||||
Router.route('/demo/login').get(demoLoginRoute.get);
 | 
			
		||||
Router.route('/').get(startpageRoute.get);
 | 
			
		||||
 | 
			
		||||
export default Router;
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,23 @@
 | 
			
		||||
import express, { Express } from 'express';
 | 
			
		||||
import { __path, prisma } from '../index.js';
 | 
			
		||||
import * as Sentry from '@sentry/node';
 | 
			
		||||
 | 
			
		||||
// Route imports
 | 
			
		||||
import frontend_routes from './frontend/index.js';
 | 
			
		||||
import static_routes from './static/index.js';
 | 
			
		||||
import api_routes from './api/index.js';
 | 
			
		||||
import auth_routes from './auth/index.js';
 | 
			
		||||
 | 
			
		||||
const Router = express.Router({ strict: false });
 | 
			
		||||
 | 
			
		||||
Router.use('/static', static_routes);
 | 
			
		||||
Router.use('/api', api_routes);
 | 
			
		||||
Router.use('/auth', auth_routes);
 | 
			
		||||
Router.use('/', frontend_routes);
 | 
			
		||||
 | 
			
		||||
// The error handler must be before any other error middleware and after all controllers
 | 
			
		||||
Router.use(Sentry.Handlers.errorHandler());
 | 
			
		||||
 | 
			
		||||
// Default route.
 | 
			
		||||
Router.all('*', function (req, res) {
 | 
			
		||||
	// TODO: Respond based on content-type (with req.is('application/json'))
 | 
			
		||||
@@ -23,3 +29,4 @@ Router.all('*', function (req, res) {
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default Router;
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user