Password scope added : GWM
This commit is contained in:
parent
467e0c2634
commit
47f96ece22
@ -17,12 +17,12 @@ exports.login = async (req, res) => {
|
||||
let userData = null;
|
||||
|
||||
// Try EstablishmentUser first
|
||||
userData = await EstablishmentUser.findOne({ where: { email } });
|
||||
userData = await EstablishmentUser.scope("withSensitive").findOne({ where: { email } });
|
||||
if (userData) {
|
||||
userRole = "EstablishmentUser";
|
||||
} else {
|
||||
// Try Admin user
|
||||
userData = await User.findOne({ where: { email } });
|
||||
userData = await User.scope("withSensitive").findOne({ where: { email } });
|
||||
if (userData) {
|
||||
userRole = "Admin";
|
||||
}
|
||||
@ -74,17 +74,16 @@ exports.login = async (req, res) => {
|
||||
});
|
||||
|
||||
// Set token in HTTP-only cookie (IMPORTANT PART)
|
||||
const isProd = process.env.NODE_ENV === "production";
|
||||
|
||||
res.cookie("auth_token", token, {
|
||||
// httpOnly: true,
|
||||
// secure: process.env.NODE_ENV === "production", // true in prod (HTTPS)
|
||||
// sameSite: "lax", // or "strict" if suitable
|
||||
// maxAge: 6 * 60 * 60 * 1000, // 6 hours in ms
|
||||
httpOnly: true,
|
||||
secure: true,
|
||||
sameSite: "none",
|
||||
maxAge: 6 * 60 * 60 * 1000, // 6 hours in ms
|
||||
secure: isProd, // only true in production (HTTPS)
|
||||
sameSite: isProd ? "none" : "lax", // 'none' requires HTTPS, so use 'lax' locally
|
||||
maxAge: 6 * 60 * 60 * 1000, // 6 hours
|
||||
});
|
||||
|
||||
|
||||
// Optionally return minimal user info (WITHOUT password)
|
||||
return res.status(200).json({
|
||||
status: "success",
|
||||
|
||||
@ -1,100 +1,120 @@
|
||||
module.exports = (sequelize, DataTypes) => {
|
||||
const EstablishmentUser = sequelize.define(
|
||||
"establishment_users",
|
||||
{
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
},
|
||||
establishment_id: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
},
|
||||
name: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
email: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
unique: true,
|
||||
},
|
||||
password: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
gender: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
},
|
||||
is_active: {
|
||||
type: DataTypes.BOOLEAN,
|
||||
defaultValue: true,
|
||||
},
|
||||
created_at: {
|
||||
type: DataTypes.DATE,
|
||||
defaultValue: DataTypes.NOW,
|
||||
},
|
||||
created_by: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
},
|
||||
updated_at: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true,
|
||||
},
|
||||
updated_by: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
},
|
||||
last_login: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true,
|
||||
},
|
||||
reset_otp: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
},
|
||||
reset_otp_expires_at: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true,
|
||||
const EstablishmentUser = sequelize.define(
|
||||
"establishment_users",
|
||||
{
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
},
|
||||
|
||||
establishment_id: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
},
|
||||
|
||||
name: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
|
||||
email: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
unique: true,
|
||||
},
|
||||
|
||||
password: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false,
|
||||
},
|
||||
|
||||
gender: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
},
|
||||
|
||||
is_active: {
|
||||
type: DataTypes.BOOLEAN,
|
||||
defaultValue: true,
|
||||
},
|
||||
|
||||
created_at: {
|
||||
type: DataTypes.DATE,
|
||||
defaultValue: DataTypes.NOW,
|
||||
},
|
||||
|
||||
created_by: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: false,
|
||||
},
|
||||
|
||||
updated_at: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true,
|
||||
},
|
||||
|
||||
updated_by: {
|
||||
type: DataTypes.INTEGER,
|
||||
allowNull: true,
|
||||
},
|
||||
|
||||
last_login: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true,
|
||||
},
|
||||
|
||||
reset_otp: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: true,
|
||||
},
|
||||
|
||||
reset_otp_expires_at: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
// ============================================================
|
||||
// Model Options
|
||||
// ============================================================
|
||||
timestamps: false,
|
||||
tableName: "establishment_users",
|
||||
|
||||
// 1. Hide sensitive fields by default
|
||||
defaultScope: {
|
||||
attributes: {
|
||||
exclude: ["password", "reset_otp", "reset_otp_expires_at"],
|
||||
},
|
||||
},
|
||||
{
|
||||
timestamps: false,
|
||||
tableName: "establishment_users",
|
||||
|
||||
// 2. Scope for login / sensitive queries
|
||||
scopes: {
|
||||
withSensitive: {
|
||||
attributes: {
|
||||
include: ["password", "reset_otp", "reset_otp_expires_at"],
|
||||
},
|
||||
},
|
||||
},
|
||||
// {
|
||||
// // 1. EXCLUDE sensitive fields from all queries
|
||||
// defaultScope: {
|
||||
// attributes: { exclude: ["password", "reset_otp", "reset_otp_expires_at"] },
|
||||
// },
|
||||
}
|
||||
);
|
||||
|
||||
// // -------------------------------------------------------------
|
||||
// // 2. Special scope for login or OTP flows
|
||||
// // Use: User.scope("withSensitive").findOne(...)
|
||||
// // -------------------------------------------------------------
|
||||
// scopes: {
|
||||
// withSensitive: {
|
||||
// attributes: {
|
||||
// include: ["password", "reset_otp", "reset_otp_expires_at"],
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
);
|
||||
|
||||
EstablishmentUser.associate = (models) => {
|
||||
|
||||
EstablishmentUser.belongsTo(models.Establishment, {
|
||||
foreignKey: 'establishment_id',
|
||||
as: 'establishments',
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
|
||||
return EstablishmentUser;
|
||||
// 3. Remove sensitive fields from all API responses
|
||||
EstablishmentUser.prototype.toJSON = function () {
|
||||
const values = { ...this.get() };
|
||||
delete values.password;
|
||||
delete values.reset_otp;
|
||||
delete values.reset_otp_expires_at;
|
||||
return values;
|
||||
};
|
||||
|
||||
|
||||
// Relationships
|
||||
EstablishmentUser.associate = (models) => {
|
||||
EstablishmentUser.belongsTo(models.Establishment, {
|
||||
foreignKey: "establishment_id",
|
||||
as: "establishments",
|
||||
});
|
||||
};
|
||||
|
||||
return EstablishmentUser;
|
||||
};
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
module.exports = (sequelize, DataTypes) => {
|
||||
const User = sequelize.define("admin_users", {
|
||||
const User = sequelize.define(
|
||||
"admin_users",
|
||||
{
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
autoIncrement: true,
|
||||
@ -35,24 +37,24 @@ module.exports = (sequelize, DataTypes) => {
|
||||
defaultValue: true,
|
||||
},
|
||||
},
|
||||
// {
|
||||
// // 1. EXCLUDE sensitive fields from all queries
|
||||
// defaultScope: {
|
||||
// attributes: { exclude: ["password", "reset_otp", "reset_otp_expires_at"] },
|
||||
// },
|
||||
{
|
||||
// 1. EXCLUDE sensitive fields from all queries
|
||||
defaultScope: {
|
||||
attributes: { exclude: ["password", "reset_otp", "reset_otp_expires_at"] },
|
||||
},
|
||||
|
||||
// // -------------------------------------------------------------
|
||||
// // 2. Special scope for login or OTP flows
|
||||
// // Use: User.scope("withSensitive").findOne(...)
|
||||
// // -------------------------------------------------------------
|
||||
// scopes: {
|
||||
// withSensitive: {
|
||||
// attributes: {
|
||||
// include: ["password", "reset_otp", "reset_otp_expires_at"],
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
// }
|
||||
// -------------------------------------------------------------
|
||||
// 2. Special scope for login or OTP flows
|
||||
// Use: User.scope("withSensitive").findOne(...)
|
||||
// -------------------------------------------------------------
|
||||
scopes: {
|
||||
withSensitive: {
|
||||
attributes: {
|
||||
include: ["password", "reset_otp", "reset_otp_expires_at"],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
return User;
|
||||
|
||||
@ -3,11 +3,13 @@ const { NotificationTemplate } = require("../models"); // adjust path if needed
|
||||
const logger = require("../services/logger");
|
||||
require("dotenv").config();
|
||||
|
||||
const port = Number(process.env.MAIL_PORT);
|
||||
|
||||
const transporter = nodemailer.createTransport({
|
||||
host: process.env.MAIL_HOST,
|
||||
port: process.env.MAIL_PORT,
|
||||
secure: false, // true for 465, false for 587
|
||||
port,
|
||||
secure: port === 465, // SSL
|
||||
requireTLS: port === 587, // Enforce TLS for 587
|
||||
auth: {
|
||||
user: process.env.MAIL_USER,
|
||||
pass: process.env.MAIL_PASS,
|
||||
|
||||
Loading…
Reference in New Issue
Block a user