-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* β App >> Adding '@nuxtjs/auth'. * β¨ Login >> Creating Authentication Form and Login page. No function behind it yet. * β¨ Register >> Adding register page. * π Auth >> Securing frontend pages only accessible after login, except for a few exceptions. * π Sidebar >> Hiding pages if user is not logged in. * π½οΈ REST Api >> Adding empty endpoints for user authentication. * β App >> Adding 'mongoose' db. * β App >> Adding 'bcrypt' for encprytion. * π¨ Controller >> Changing naming for scripts controller. * β App >> Dont wanna mongoose! * β App >> Adding 'lowdb'. Should be enough for my purpose! π * π¨ Scripts >> Changing controller naming. * π½οΈ REST Api >> Adding modul, controller and route to register a user. No checks right now... just dumb registering in a local lowdb database. * β App >> Adding passport and JWT packages. * π GitIgnore >> Adding database file. * β App >> Adding 'cookie-parser' for express server. * π½οΈ REST Api >> Adding login and user authentication handling. * β App >> Nuxt Auth Modul gewechselt. * π½οΈ REST Api >> Less response messages on auth routes. * ποΈ Nuxt/Express >> Changing/separating folder structure. * β App >> Adding "concurrently" for starting multiple scripts at once. * π½οΈ Nuxt >> Deactivating Auth for now. * π½οΈ REST Api >> Separating routes from app. Also deactivating auth for now. * β¬οΈ App >> Updating [email protected] * β»οΈ REST Api >> Refactoring Express server. Using ESM Syntax. * β App >> Adding dotenv for using .env variables. * β»οΈ REST Api >> Refactoring Auth moduls for ESM Syntax. * π¨ App >> Activating Auth Modul in Nuxt. Not functioning right now! * π REST Api >> Bugfixing jwt auth implementation. * π¨ Linter >> Fixing Linter settings. * π Login >> Showing user info if already logged in. * β¨ Logout >> Sidebar button - logging out. * π App >> Better Update Display. * π½οΈ REST Api >> Only allows one user registration right now. Frontend is reacting to this and only displays login/register pages if possible. * π¨ Auth >> Preparations for creating a secret token if no one exists. * ποΈ Authentication >> Refactoring the generation of secret key. * π₯ App >> Removing default nuxt files. * π₯ App >> Changing nuxt to client side rendering. Hole app is gonna served over the express server. * π₯ App >> Changing PM2 starting script. * π App >> Removing dev log. * β App >> Adding cross-env for setting cross platform env variable. * π¨ App >> Testing Env setting * π App >> Changing console.logs for App start. * π v0.0.1-alpha.2
- Loading branch information
Showing
36 changed files
with
1,411 additions
and
205 deletions.
There are no files selected for viewing
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -91,3 +91,6 @@ sw.* | |
|
||
# Custom user scripts | ||
/scripts/custom | ||
|
||
# Database | ||
db.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
// Imports | ||
import createError from 'http-errors' | ||
import express from 'express' | ||
import cors from 'cors' | ||
import cookieParser from 'cookie-parser' | ||
|
||
// Authentication Import | ||
import passport from 'passport' | ||
|
||
// Importing Routes | ||
import baseRoutes from './router.js' | ||
|
||
// Development | ||
const isDev = process.env.NODE_ENV === 'development' | ||
console.log('[App] -> Development:', isDev) | ||
|
||
// Config | ||
const PORT = process.env.PORT || 8800 // Default Port: 8800 | ||
|
||
// Express Init | ||
const app = express() | ||
if (isDev) app.use(cors()) // CORS policy only in dev | ||
app.use(express.static('dist')) | ||
app.use(express.json()) | ||
app.use(express.urlencoded({ extended: true })) // for form data | ||
app.use(cookieParser()) // Cookies | ||
app.use(passport.initialize()) // Authentication | ||
|
||
// Router/Endpoints | ||
const baseUrl = '/api/v1' | ||
baseRoutes(app, baseUrl) | ||
|
||
// Catch 404 and forward to error handler | ||
app.use((req, res, next) => { | ||
next(createError(404)) | ||
}) | ||
|
||
// Error handler | ||
app.use((err, req, res, next) => { | ||
console.error('Request Url:', req.originalUrl) | ||
|
||
// Set locals, only providing error in development | ||
res.locals.message = err.message | ||
res.locals.error = req.app.get('env') === 'development' ? err : {} | ||
|
||
// Render the error page | ||
res.status(err.status || 500) | ||
res.json({ | ||
_status: 'error', | ||
err | ||
}) | ||
}) | ||
|
||
// Listening on port | ||
app.listen(PORT, () => { | ||
console.log(`[App] -> App is running on ${PORT}`) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
import { join } from 'path' | ||
import crypto from 'crypto' | ||
import fs from 'fs-extra' | ||
import bcrypt from 'bcrypt' | ||
import passport from 'passport' | ||
import LocalStrategy from 'passport-local' | ||
import JwtStrategy from 'passport-jwt' | ||
import jwt from 'jsonwebtoken' | ||
import User from '../models/user.js' | ||
|
||
// const authUserSecret = getAuthUserSecret() // process.env.AUTH_USER_SECRET | ||
getAuthUserSecret() | ||
|
||
// Returning or if it not exists generating a authentication secret key | ||
async function getAuthUserSecret() { | ||
// Getting Env if available | ||
const secret = process.env.AUTH_USER_SECRET || false | ||
|
||
// If Env variable is not existing, we will generate one | ||
if (!secret) { | ||
const generatedKey = crypto.randomBytes(256).toString('hex') | ||
process.env.AUTH_USER_SECRET = generatedKey | ||
|
||
// Saving key in '.env' file | ||
const filePath = join('.', '.env') | ||
const content = `AUTH_USER_SECRET=${generatedKey}` | ||
await fs.outputFile(filePath, content).catch((error) => { | ||
console.error(error) | ||
throw error | ||
}) | ||
return generatedKey | ||
} | ||
return secret | ||
} | ||
|
||
// Setting up passport for email/password authentication | ||
passport.use(new LocalStrategy.Strategy({ usernameField: 'email', passwordField: 'password' }, async function(email, password, done) { | ||
await User.GetUser(email) | ||
.then((user) => { | ||
return user | ||
}).then(async(user) => { | ||
if (!user) { | ||
return done(null, false, { message: 'Authentication failed' }) | ||
} | ||
const validation = await comparePasswords(password, user.password) | ||
if (validation) { | ||
return done(null, user) | ||
} else { | ||
return done(null, false, { message: 'Authentication failed' }) | ||
} | ||
}).catch((err) => { | ||
return done(err) | ||
}) | ||
})) | ||
|
||
// Extracting JWT Token out of cookies | ||
const tokenExtractor = function(req) { | ||
let token = null | ||
let reqCookie = null | ||
let reqHeader = null | ||
|
||
// Extracting 'jwt' token from two different places | ||
try { | ||
if (req && req.cookies && req.cookies['auth._token.local']) { | ||
reqCookie = req.cookies['auth._token.local'] | ||
} else if (req.req && req.req.cookies && req.req.cookies['auth._token.local']) { | ||
reqCookie = req.req.cookies['auth._token.local'] | ||
} else if (req.headers && req.headers && req.headers.authorization) { | ||
reqHeader = req.headers.authorization | ||
} else if (req.req.headers && req.req.headers && req.req.headers.authorization) { | ||
reqHeader = req.req.headers.authorization | ||
} | ||
} catch (error) { | ||
// console.error(error) | ||
return null | ||
} | ||
|
||
if (reqCookie) { | ||
const rawToken = reqCookie.toString() | ||
token = rawToken.slice(rawToken.indexOf(' ') + 1, rawToken.length) | ||
} else if (reqHeader) { | ||
token = reqHeader.slice(reqHeader.indexOf(' ') + 1, reqHeader.length) | ||
} | ||
return token | ||
} | ||
|
||
/* | ||
const options = { | ||
// tokenExtractor | ||
// JwtStrategy.ExtractJwt.fromAuthHeaderAsBearerToken() | ||
// JwtStrategy.ExtractJwt.fromExtractors([tokenExtractor, JwtStrategy.ExtractJwt.fromHeader('authorization'), JwtStrategy.ExtractJwt.fromAuthHeaderAsBearerToken()]) | ||
jwtFromRequest: tokenExtractor, | ||
secretOrKey: process.env.AUTH_USER_SECRET // authUserSecret | ||
} | ||
*/ | ||
|
||
// Setting up passport for JWT Token authentication | ||
passport.use(new JwtStrategy.Strategy({ jwtFromRequest: tokenExtractor, secretOrKey: process.env.AUTH_USER_SECRET }, async function(jwtPayload, done) { | ||
await User.GetUser(jwtPayload.email) // Or 'GetUser' - without 'User.' | ||
.then((user) => { | ||
if (user) { | ||
return done(null, { | ||
email: user.email | ||
}) | ||
} else { | ||
return done(null, false, 'Failed') | ||
} | ||
}) | ||
.catch((err) => { | ||
console.error(err) | ||
return done(err) | ||
}) | ||
})) | ||
|
||
/** | ||
* Take a string and return a generated hash | ||
* @name generatePasswordHash | ||
* @function | ||
* @memberof module:routers/auth | ||
*/ | ||
async function generatePasswordHash(plainPassword) { | ||
return await bcrypt.hash(plainPassword, 12) | ||
} | ||
|
||
// Compares password from plaintext and hashed one | ||
async function comparePasswords(plainPassword, hashedPassword) { | ||
return await bcrypt.compare(plainPassword, hashedPassword) | ||
} | ||
|
||
/** | ||
* Returns generated token for authentication | ||
* @name signUserToken | ||
* @function | ||
* @memberof module:routers/auth | ||
*/ | ||
function signUserToken(user) { | ||
return jwt.sign({ | ||
id: user.id, | ||
email: user.email | ||
}, process.env.AUTH_USER_SECRET) // authUserSecret | ||
} | ||
|
||
/** | ||
* Proxy for CreateUser model function - creates a user in database | ||
* @name CreateUser | ||
* @function | ||
* @memberof module:routers/auth | ||
*/ | ||
async function CreateUser(user) { | ||
return await User.CreateUser(user) | ||
} | ||
|
||
/** | ||
* Proxy for CountUsers model function - counts how many users registered, or returns false | ||
* @name CountUsers | ||
* @function | ||
* @memberof module:routers/auth | ||
*/ | ||
async function CountUsers() { | ||
return await User.CountUsers() | ||
} | ||
|
||
export default { | ||
CreateUser, | ||
CountUsers, | ||
generatePasswordHash, | ||
signUserToken | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.