face / src /models /User.js
aliroohan179's picture
feat: implement core backend POS API with authentication, role-based access control, menu management, and order processing logic.
1e480b5
Raw History Blame Contribute Delete
1.43 kB
const mongoose = require('mongoose');
const bcrypt = require('bcryptjs');
const userSchema = new mongoose.Schema(
{
name: { type: String, required: true, trim: true },
username: { type: String, required: true, unique: true, lowercase: true, trim: true },
password: { type: String, required: true, minlength: 6 },
role: { type: String, enum: ['owner', 'cashier'], default: 'cashier' },
active: { type: Boolean, default: true },
adminPin: { type: String, default: null }, // 4-digit PIN for owner, used for void/refund
},
{ timestamps: true }
);
// Hash password and adminPin before save (single hook — async, no `next`)
userSchema.pre('save', async function () {
if (this.isModified('password') && this.password) {
this.password = await bcrypt.hash(this.password, 12);
}
if (this.isModified('adminPin') && this.adminPin) {
this.adminPin = await bcrypt.hash(this.adminPin, 12);
}
});
userSchema.methods.matchPassword = function (entered) {
return bcrypt.compare(entered, this.password);
};
userSchema.methods.matchPin = function (entered) {
if (!this.adminPin) return Promise.resolve(false);
return bcrypt.compare(entered, this.adminPin);
};
// Never return password in JSON responses
userSchema.set('toJSON', {
transform: (_, obj) => {
delete obj.password;
delete obj.adminPin;
return obj;
},
});
module.exports = mongoose.model('User', userSchema);