implement basic auth flow
This commit is contained in:
parent
1b2f7b57e6
commit
e5ad7961b3
|
@ -0,0 +1,71 @@
|
||||||
|
import passport from 'passport'
|
||||||
|
import { Strategy as localStrategy } from 'passport-local'
|
||||||
|
import { User, encryptPwd, pwdIsValid } from '../model/model.mjs'
|
||||||
|
import { Strategy as JWTstrategy, ExtractJwt } from 'passport-jwt'
|
||||||
|
import { userDb } from '../db.mjs'
|
||||||
|
|
||||||
|
passport.use('signup', new localStrategy(
|
||||||
|
{
|
||||||
|
usernameField: 'username',
|
||||||
|
passwordField: 'password'
|
||||||
|
},
|
||||||
|
async (username, password, done) => {
|
||||||
|
console.log("signup auth strategy has begun")
|
||||||
|
try {
|
||||||
|
const encryptedPwd = await encryptPwd(password)
|
||||||
|
const user = await userDb("users").insert({ username: username, password: encryptedPwd }).returning(["username", "password"])
|
||||||
|
console.log(`user: ${user}`)
|
||||||
|
return done(null, user)
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
done(err)
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
passport.use('login',
|
||||||
|
new localStrategy(
|
||||||
|
{
|
||||||
|
usernameField: "username",
|
||||||
|
passwordField: "password",
|
||||||
|
session: false
|
||||||
|
},
|
||||||
|
async (email, password, done) => {
|
||||||
|
console.log("local strategy called")
|
||||||
|
try {
|
||||||
|
let returnedUser: Array<User> = await userDb("users").select("username", "password").where({ username: email })
|
||||||
|
const user: User = returnedUser[0]
|
||||||
|
console.log(`user: ${user}`)
|
||||||
|
if (!user || returnedUser.length === 0) {
|
||||||
|
return done(null, false, { message: "user not found" })
|
||||||
|
}
|
||||||
|
|
||||||
|
const validate: boolean = await pwdIsValid(password, user)
|
||||||
|
console.log(`isValidPassword? ${validate}`)
|
||||||
|
|
||||||
|
if (!validate) {
|
||||||
|
return done(null, false, { message: "wrong password" })
|
||||||
|
}
|
||||||
|
|
||||||
|
return done(null, user, { message: "logged in successfully" })
|
||||||
|
} catch (error) {
|
||||||
|
return done(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
passport.use(
|
||||||
|
new JWTstrategy(
|
||||||
|
{
|
||||||
|
secretOrKey: "TOP_SECRET",
|
||||||
|
jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('secret_token')
|
||||||
|
},
|
||||||
|
async (token, done) => {
|
||||||
|
try {
|
||||||
|
return done(null, token.user)
|
||||||
|
} catch (error) {
|
||||||
|
done(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
|
@ -0,0 +1,28 @@
|
||||||
|
import knex from "knex";
|
||||||
|
|
||||||
|
export const db = knex({
|
||||||
|
client: 'sqlite3',
|
||||||
|
connection: {
|
||||||
|
filename: "./submissions"
|
||||||
|
},
|
||||||
|
useNullAsDefault: true
|
||||||
|
})
|
||||||
|
|
||||||
|
export const testDb = knex({
|
||||||
|
client: 'sqlite3',
|
||||||
|
connection: {
|
||||||
|
filename: "./test.db"
|
||||||
|
},
|
||||||
|
useNullAsDefault: true
|
||||||
|
})
|
||||||
|
|
||||||
|
export const userDb = knex({
|
||||||
|
client: "sqlite3",
|
||||||
|
connection: {
|
||||||
|
filename: "./users"
|
||||||
|
},
|
||||||
|
useNullAsDefault: true
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,15 @@
|
||||||
|
import bodyParser from 'body-parser';
|
||||||
import express from 'express';
|
import express from 'express';
|
||||||
|
import passport from 'passport';
|
||||||
|
import { default as nonSecureRoutes } from "./routes/routes.mjs"
|
||||||
|
import { default as secureRoutes } from "./routes/secure-routes.mjs"
|
||||||
|
import "./auth/auth.mjs"
|
||||||
const app = express();
|
const app = express();
|
||||||
const port = 3000;
|
const port = 3000;
|
||||||
|
app.use(passport.initialize())
|
||||||
app.get('/', (req, res) => {
|
app.use(bodyParser.json())
|
||||||
res.send('Hello World!');
|
app.use("/", nonSecureRoutes)
|
||||||
});
|
app.use("/app", secureRoutes)
|
||||||
|
|
||||||
app.listen(port, () => {
|
app.listen(port, () => {
|
||||||
return console.log(`Express is listening at http://localhost:${port}`);
|
return console.log(`Express is listening at http://localhost:${port}`);
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
import bcrypt from "bcrypt"
|
||||||
|
|
||||||
|
export interface User {
|
||||||
|
username: string;
|
||||||
|
password: string;
|
||||||
|
_id?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function encryptPwd(pwd: string) {
|
||||||
|
return Promise.resolve(bcrypt.hash(pwd, 10))
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function pwdIsValid(pwd: string, user: User): Promise<boolean> {
|
||||||
|
return Promise.resolve(bcrypt.compare(pwd, user.password))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
import express from "express"
|
||||||
|
import passport from "passport"
|
||||||
|
import jwt from 'jsonwebtoken';
|
||||||
|
import { User } from "../model/model.mjs";
|
||||||
|
|
||||||
|
const router = express.Router()
|
||||||
|
|
||||||
|
router.post("/signup",
|
||||||
|
passport.authenticate("signup", { session: false }),
|
||||||
|
async (req, res, next) => {
|
||||||
|
res.json({
|
||||||
|
message: "signup successful",
|
||||||
|
user: req.user
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
router.post(
|
||||||
|
'/login',
|
||||||
|
async (req, res, next) => {
|
||||||
|
passport.authenticate(
|
||||||
|
'login',
|
||||||
|
async (err: Error, user: User, _: any) => {
|
||||||
|
try {
|
||||||
|
if (err || !user) {
|
||||||
|
const error = new Error('An error occurred.');
|
||||||
|
|
||||||
|
return next(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
req.login(
|
||||||
|
user,
|
||||||
|
{ session: false },
|
||||||
|
async (error) => {
|
||||||
|
if (error) return next(error);
|
||||||
|
|
||||||
|
const body = { _id: user._id, username: user.username };
|
||||||
|
const token = jwt.sign({ user: body }, 'TOP_SECRET', { expiresIn: "20m" });
|
||||||
|
|
||||||
|
return res.json({ token });
|
||||||
|
}
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return next(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)(req, res, next);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
export default router
|
|
@ -0,0 +1,15 @@
|
||||||
|
import express from "express"
|
||||||
|
const router = express.Router()
|
||||||
|
|
||||||
|
router.get(
|
||||||
|
'/profile',
|
||||||
|
(req, res, next) => {
|
||||||
|
res.json({
|
||||||
|
message: "you made it to the secure route",
|
||||||
|
user: req.user,
|
||||||
|
token: req.query.secret_token,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export default router
|
Loading…
Reference in New Issue