Skip to content

Instantly share code, notes, and snippets.

@wmantly
Created January 3, 2024 20:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wmantly/2097c9abafda5b83ebfd3b6ed10aa967 to your computer and use it in GitHub Desktop.
Save wmantly/2097c9abafda5b83ebfd3b6ed10aa967 to your computer and use it in GitHub Desktop.
'use strict';
const { Model } = require('sequelize');
module.exports = (sequelize, DataTypes) => {
class AuthToken extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
this.belongsTo(models.User, {foreignKey: 'created_by'})
}
}
AuthToken.init({
token:{
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
allowNull: false,
primaryKey: true
},
created_by: {
type: DataTypes.STRING,
references: {
model: 'Users',
key: 'username'
}
},
expires_on: {
type: DataTypes.DATE,
allowNull: true
},
is_valid: {
type: DataTypes.BOOLEAN,
defaultValue: true
}
}, {
sequelize,
modelName: 'AuthToken',
});
return AuthToken;
};
'use strict';
const { Model } = require('sequelize');
const bcrypt = require('bcrypt');
const saltRounds = 10;
module.exports = (sequelize, DataTypes) => {
class User extends Model {
/**
* Helper method for defining associations.
* This method is not a part of Sequelize lifecycle.
* The `models/index` file will call this method automatically.
*/
static associate(models) {
this.hasMany(models.AuthToken, {foreignKey: 'created_by'})
}
static async login(data){
try{
let user = await this.findByPk(data.username);
if(await bcrypt.compare(data.password, user.password)){
return user
}else{
throw new Error('Login failed!');
}
}catch(error){
console.error('sql user login error:', error);
throw new Error('Login failed!');
}
}
}
User.init({
username:{
type: DataTypes.STRING,
primaryKey: true,
unique: true,
},
password: DataTypes.STRING
}, {
sequelize,
modelName: 'User',
sync: true,
hooks: {
beforeCreate: async (user) => {
if (user.password) {
user.password = await bcrypt.hash(user.password, saltRounds);
}
},
beforeUpdate: async (user) => {
if (user.password) {
user.password = await bcrypt.hash(user.password, saltRounds);
}
}
}
});
return User;
};
'use strict';
const router = require('express').Router();
const {User} = require('../models/user');
const {Auth, AuthToken} = require('../models/auth');
router.post('/login', async function(req, res, next){
try{
let auth = await Auth.login(req.body);
return res.json({
login: true,
token: auth.token.token,
});
}catch(error){
next(error);
}
});
router.all('/logout', async function(req, res, next){
try{
if(req.user){
await req.user.logout();
}
res.json({message: 'Bye'})
}catch(error){
next(error);
}
});
router.post('/invite/:token', async function(req, res, next) {
try{
req.body.token = req.params.token;
let user = await User.addByInvite(req.body);
let token = await AuthToken.add(user);
return res.json({
user: user.username,
token: token.token
});
}catch(error){
next(error);
}
});
module.exports = router;
'use strict';
const router = require('express').Router();
const {User} = require('../models/user');
router.get('/', async function(req, res, next){
try{
return res.json({
results: await User[req.query.detail ? "listDetail" : "list"]()
});
}catch(error){
next(error);
}
});
router.post('/', async function(req, res, next){
try{
req.body.created_by = req.user.username
return res.json({results: await User.add(req.body)});
}catch(error){
next(error);
}
});
router.delete('/:username', async function(req, res, next){
try{
let user = await User.get(req.params.username);
return res.json({username: req.params.username, results: await user.remove()})
}catch(error){
next(error);
}
});
router.get('/me', async function(req, res, next){
try{
return res.json({username: req.user.username});
}catch(error){
next(error);
}
});
router.put('/password', async function(req, res, next){
try{
return res.json({results: await req.user.setPassword(req.body)})
}catch(error){
next(error);
}
});
router.put('/password/:username', async function(req, res, next){
try{
let user = await User.get(req.params.username);
return res.json({results: await user.setPassword(req.body)});
}catch(error){
next(error);
}
});
router.post('/invite', async function(req, res, next){
try{
let token = await req.user.invite();
return res.json({token: token.token});
}catch(error){
next(error);
}
});
module.exports = router;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment