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