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 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 port = 3000;
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
res.send('Hello World!');
|
||||
});
|
||||
app.use(passport.initialize())
|
||||
app.use(bodyParser.json())
|
||||
app.use("/", nonSecureRoutes)
|
||||
app.use("/app", secureRoutes)
|
||||
|
||||
app.listen(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