- risolto problema della non attesa della PWA durante la chiamata a Node.js.
- risolto problema dell'ambiente in Locale HTTPS certificato installato aggiornato.
This commit is contained in:
@@ -21,8 +21,8 @@ DELAY_SENDEMAIL=2000
|
|||||||
VAPI_KEY_SUBJECT=mailto:paolo@freeplanet.app
|
VAPI_KEY_SUBJECT=mailto:paolo@freeplanet.app
|
||||||
PUBLIC_VAPI_KEY=BDncvMiUZmjaCG2Kr1V9N0_33hOG-AuNSbHSvL24y2dzBiUjAxKm02emx5SeJvz2IGmtRf6YqCgopeQwCwUmZw8
|
PUBLIC_VAPI_KEY=BDncvMiUZmjaCG2Kr1V9N0_33hOG-AuNSbHSvL24y2dzBiUjAxKm02emx5SeJvz2IGmtRf6YqCgopeQwCwUmZw8
|
||||||
PRIVATE_VAPI_KEY=uB2-jQkrbysyDtqN3ziMBDsVn0wdEaDsksX81zoOGQo
|
PRIVATE_VAPI_KEY=uB2-jQkrbysyDtqN3ziMBDsVn0wdEaDsksX81zoOGQo
|
||||||
PATH_CERT_KEY=localhost.key
|
PATH_CERT_KEY=localhost-key.pem
|
||||||
PATH_SERVER_CRT=localhost.crt
|
PATH_SERVER_CRT=localhost.pem
|
||||||
PATH_SSL_ROOT_PEM=root.pem
|
PATH_SSL_ROOT_PEM=root.pem
|
||||||
PATH_SSL_CHAIN_PEM=chain.pem
|
PATH_SSL_CHAIN_PEM=chain.pem
|
||||||
GCM_API_KEY=""
|
GCM_API_KEY=""
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ DELAY_SENDEMAIL=2000
|
|||||||
VAPI_KEY_SUBJECT=mailto:paolo@freeplanet.app
|
VAPI_KEY_SUBJECT=mailto:paolo@freeplanet.app
|
||||||
PUBLIC_VAPI_KEY=BDncvMiUZmjaCG2Kr1V9N0_33hOG-AuNSbHSvL24y2dzBiUjAxKm02emx5SeJvz2IGmtRf6YqCgopeQwCwUmZw8
|
PUBLIC_VAPI_KEY=BDncvMiUZmjaCG2Kr1V9N0_33hOG-AuNSbHSvL24y2dzBiUjAxKm02emx5SeJvz2IGmtRf6YqCgopeQwCwUmZw8
|
||||||
PRIVATE_VAPI_KEY=uB2-jQkrbysyDtqN3ziMBDsVn0wdEaDsksX81zoOGQo
|
PRIVATE_VAPI_KEY=uB2-jQkrbysyDtqN3ziMBDsVn0wdEaDsksX81zoOGQo
|
||||||
PATH_CERT_KEY=localhost.key
|
PATH_CERT_KEY=localhost-key.pem
|
||||||
PATH_SERVER_CRT=localhost.crt
|
PATH_SERVER_CRT=localhost.pem
|
||||||
PATH_SSL_ROOT_PEM=root.pem
|
PATH_SSL_ROOT_PEM=root.pem
|
||||||
PATH_SSL_CHAIN_PEM=chain.pem
|
PATH_SSL_CHAIN_PEM=chain.pem
|
||||||
GCM_API_KEY=""
|
GCM_API_KEY=""
|
||||||
|
|||||||
1
localhost-key.pem
Symbolic link
1
localhost-key.pem
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/Users/suryapaolo/certs/localhost-key.pem
|
||||||
1
localhost.pem
Symbolic link
1
localhost.pem
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
/Users/suryapaolo/certs/localhost.pem
|
||||||
@@ -30,10 +30,12 @@ const authenticate = async (req, res, next) => {
|
|||||||
|
|
||||||
const access = 'auth';
|
const access = 'auth';
|
||||||
|
|
||||||
const idapp = getIdApp(req);
|
//const idapp = getIdApp(req);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const ris = await User.findByToken(token, access, true, idapp);
|
console.log(' ### Authenticate: token', !!token);
|
||||||
|
|
||||||
|
const ris = await User.findByToken(token, access, true, false);
|
||||||
if (ris && ris.user && !!ris.user.deleted) {
|
if (ris && ris.user && !!ris.user.deleted) {
|
||||||
if (ris.user.deleted)
|
if (ris.user.deleted)
|
||||||
ris.user = null;
|
ris.user = null;
|
||||||
@@ -48,6 +50,7 @@ const authenticate = async (req, res, next) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!!ris.user) {
|
if (!!ris.user) {
|
||||||
|
console.log(' AUTH 2) ');
|
||||||
// crea una funzione per aggiornare il lasttimeonline e useragent
|
// crea una funzione per aggiornare il lasttimeonline e useragent
|
||||||
// Save last time online
|
// Save last time online
|
||||||
const myuser = await User.updateLastTimeAndUserAgent(ris.user._id, req.get('User-Agent'));
|
const myuser = await User.updateLastTimeAndUserAgent(ris.user._id, req.get('User-Agent'));
|
||||||
@@ -55,6 +58,68 @@ const authenticate = async (req, res, next) => {
|
|||||||
req.token = token;
|
req.token = token;
|
||||||
// req.refreshToken = refreshToken;
|
// req.refreshToken = refreshToken;
|
||||||
req.access = access;
|
req.access = access;
|
||||||
|
|
||||||
|
console.log(' AUTH 3) NEXT... ');
|
||||||
|
next(); // Esegui il codice successivo
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
tools.mylog("ERR authenticate invalid Token =", e);
|
||||||
|
if (e === server_constants.RIS_CODE_HTTP_FORBIDDEN_TOKEN_EXPIRED) {
|
||||||
|
return res.status(server_constants.RIS_CODE_HTTP_FORBIDDEN_TOKEN_EXPIRED).send();
|
||||||
|
}
|
||||||
|
res.status(server_constants.RIS_CODE_HTTP_INVALID_TOKEN).send();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const authenticate_withUser = async (req, res, next) => {
|
||||||
|
const token = req.header('x-auth');
|
||||||
|
//const refreshToken = req.header('x-refrtok');
|
||||||
|
|
||||||
|
// console.log('authenticate... ');
|
||||||
|
|
||||||
|
let noaut = false;
|
||||||
|
|
||||||
|
if (req.body.hasOwnProperty('noaut')) {
|
||||||
|
noaut = req.body.noaut;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (noaut) {
|
||||||
|
next();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const access = 'auth';
|
||||||
|
|
||||||
|
//const idapp = getIdApp(req);
|
||||||
|
|
||||||
|
try {
|
||||||
|
console.log(' ### authenticate_withUser: token', !!token);
|
||||||
|
|
||||||
|
const ris = await User.findByToken(token, access, true, true);
|
||||||
|
if (ris && ris.user && !!ris.user.deleted) {
|
||||||
|
if (ris.user.deleted)
|
||||||
|
ris.user = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ris.code === server_constants.RIS_CODE_HTTP_FORBIDDEN_TOKEN_EXPIRED) {
|
||||||
|
return res.status(server_constants.RIS_CODE_HTTP_FORBIDDEN_TOKEN_EXPIRED).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ris.user) {
|
||||||
|
return res.status(server_constants.RIS_CODE_HTTP_INVALID_TOKEN).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!!ris.user) {
|
||||||
|
console.log(' AUTH 2) ');
|
||||||
|
// crea una funzione per aggiornare il lasttimeonline e useragent
|
||||||
|
// Save last time online
|
||||||
|
await User.updateLastTimeAndUserAgent(ris.user._id, req.get('User-Agent'));
|
||||||
|
req.user = ris.user;
|
||||||
|
req.token = token;
|
||||||
|
// req.refreshToken = refreshToken;
|
||||||
|
req.access = access;
|
||||||
|
|
||||||
|
console.log(' AUTH_WITHUSER 3) NEXT... ');
|
||||||
next(); // Esegui il codice successivo
|
next(); // Esegui il codice successivo
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@@ -91,7 +156,48 @@ const authenticate_noerror = async (req, res, next) => {
|
|||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
|
|
||||||
const ris = await User.findByToken(token, 'auth', false, getIdApp(req));
|
const ris = await User.findByToken(token, 'auth', false, false);
|
||||||
|
|
||||||
|
if (ris.code !== server_constants.RIS_CODE_OK) {
|
||||||
|
req.user = null;
|
||||||
|
req.token = null;
|
||||||
|
req.code = ris.code;
|
||||||
|
} else {
|
||||||
|
req.user = ris.user;
|
||||||
|
req.token = token;
|
||||||
|
req.refreshToken = refreshToken;
|
||||||
|
req.code = ris.code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ris.code === server_constants.RIS_CODE_HTTP_FORBIDDEN_TOKEN_EXPIRED) {
|
||||||
|
return res.status(server_constants.RIS_CODE_HTTP_FORBIDDEN_TOKEN_EXPIRED).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(' ## NEXT ! AVANTI...');
|
||||||
|
next();
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Errore nel middleware di autenticazione:', e);
|
||||||
|
req.user = null;
|
||||||
|
req.token = null;
|
||||||
|
req.code = server_constants.RIS_CODE_HTTP_INVALID_TOKEN;
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const authenticate_noerror_WithUser = async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
const token = req.header('x-auth');
|
||||||
|
const refreshToken = req.header('x-refrtok');
|
||||||
|
console.log(' ### Authenticate_noerror: token', !!token);
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
req.user = null;
|
||||||
|
req.token = null;
|
||||||
|
req.code = server_constants.RIS_CODE_HTTP_INVALID_TOKEN;
|
||||||
|
console.log(' ## WITHUSER_TOKEN INVALIDO ❌ ...');
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ris = await User.findByToken(token, 'auth', false, true);
|
||||||
|
|
||||||
if (ris.code !== server_constants.RIS_CODE_OK) {
|
if (ris.code !== server_constants.RIS_CODE_OK) {
|
||||||
req.user = null;
|
req.user = null;
|
||||||
@@ -119,4 +225,46 @@ const authenticate_noerror = async (req, res, next) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = { authenticate, authenticate_noerror, auth_default };
|
const authenticate_noerror_WithUserLean = async (req, res, next) => {
|
||||||
|
try {
|
||||||
|
const token = req.header('x-auth');
|
||||||
|
const refreshToken = req.header('x-refrtok');
|
||||||
|
console.log(' ### Authenticate_noerror: token', !!token);
|
||||||
|
|
||||||
|
if (!token) {
|
||||||
|
req.user = null;
|
||||||
|
req.token = null;
|
||||||
|
req.code = server_constants.RIS_CODE_HTTP_INVALID_TOKEN;
|
||||||
|
console.log(' ## WITHUSER_TOKEN INVALIDO ❌ ...');
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ris = await User.findByToken(token, 'auth', false, true, true);
|
||||||
|
|
||||||
|
if (ris.code !== server_constants.RIS_CODE_OK) {
|
||||||
|
req.user = null;
|
||||||
|
req.token = null;
|
||||||
|
req.code = ris.code;
|
||||||
|
} else {
|
||||||
|
req.user = ris.user;
|
||||||
|
req.token = token;
|
||||||
|
req.refreshToken = refreshToken;
|
||||||
|
req.code = ris.code;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ris.code === server_constants.RIS_CODE_HTTP_FORBIDDEN_TOKEN_EXPIRED) {
|
||||||
|
return res.status(server_constants.RIS_CODE_HTTP_FORBIDDEN_TOKEN_EXPIRED).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(' ## NEXT ! AVANTI...');
|
||||||
|
next();
|
||||||
|
} catch (e) {
|
||||||
|
console.error('Errore nel middleware di autenticazione:', e);
|
||||||
|
req.user = null;
|
||||||
|
req.token = null;
|
||||||
|
req.code = server_constants.RIS_CODE_HTTP_INVALID_TOKEN;
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = { authenticate, authenticate_noerror, auth_default, authenticate_withUser, authenticate_noerror_WithUser, authenticate_noerror_WithUserLean };
|
||||||
|
|||||||
@@ -441,7 +441,7 @@ MyGroupSchema.statics.getGroupsByUsername = async function (idapp, username, req
|
|||||||
listgroups,
|
listgroups,
|
||||||
listSentRequestGroups,
|
listSentRequestGroups,
|
||||||
listRefusedGroups,
|
listRefusedGroups,
|
||||||
mygroups: req.user.profile.mygroups,
|
mygroups: await User.getMyGroupsById(req.user._id),
|
||||||
};
|
};
|
||||||
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -731,7 +731,23 @@ UserSchema.statics.isFacilitatore = function (perm) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
UserSchema.statics.findByToken = async function (token, typeaccess, con_auth, idapp) {
|
/**
|
||||||
|
* Finds a user by their authentication token.
|
||||||
|
*
|
||||||
|
* @param {string} token - The authentication token.
|
||||||
|
* @param {string} typeaccess - The type of access associated with the token.
|
||||||
|
* @param {boolean} con_auth - Whether to continue authentication if the token is expired.
|
||||||
|
* @param {string} idapp - The application ID.
|
||||||
|
* @returns {Promise<Object>} An object containing the user and a status code, indicating
|
||||||
|
* whether the token is valid, expired, or invalid.
|
||||||
|
* The user object is null if no user is found or the token is invalid.
|
||||||
|
*
|
||||||
|
* This function verifies the provided token and retrieves the corresponding user if the token is valid.
|
||||||
|
* If the token is expired and `con_auth` is false, or if the token is invalid, it returns null for the user.
|
||||||
|
* The status code reflects the validity of the token: valid, expired, or invalid.
|
||||||
|
*/
|
||||||
|
|
||||||
|
UserSchema.statics.findByToken = async function (token, typeaccess, con_auth, withuser, withlean = false) {
|
||||||
const User = this;
|
const User = this;
|
||||||
let code = server_constants.RIS_CODE_HTTP_INVALID_TOKEN;
|
let code = server_constants.RIS_CODE_HTTP_INVALID_TOKEN;
|
||||||
let user = null;
|
let user = null;
|
||||||
@@ -752,15 +768,44 @@ UserSchema.statics.findByToken = async function (token, typeaccess, con_auth, id
|
|||||||
return { user: null, code };
|
return { user: null, code };
|
||||||
}
|
}
|
||||||
|
|
||||||
user = await User.findOne({
|
let project = undefined;
|
||||||
_id: decoded.smart,
|
|
||||||
tokens: {
|
if (withuser) {
|
||||||
$elemMatch: {
|
if (withlean) {
|
||||||
token,
|
user = await User.findOne({
|
||||||
access: typeaccess,
|
_id: decoded.smart,
|
||||||
|
tokens: {
|
||||||
|
$elemMatch: {
|
||||||
|
token,
|
||||||
|
access: typeaccess,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, project).lean();
|
||||||
|
} else {
|
||||||
|
user = await User.findOne({
|
||||||
|
_id: decoded.smart,
|
||||||
|
tokens: {
|
||||||
|
$elemMatch: {
|
||||||
|
token,
|
||||||
|
access: typeaccess,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, project);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
|
||||||
|
project = { perm: 1, _id: 1, idapp: 1, username: 1, deleted: 1, aportador_solidario: 1, aportador_solidario_nome_completo: 1, 'profile.socioresidente': 1 };
|
||||||
|
|
||||||
|
user = await User.findOne({
|
||||||
|
_id: decoded.smart,
|
||||||
|
tokens: {
|
||||||
|
$elemMatch: {
|
||||||
|
token,
|
||||||
|
access: typeaccess,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
}, project).lean();
|
||||||
}).lean();
|
}
|
||||||
|
|
||||||
if (user) {
|
if (user) {
|
||||||
const checkExpiry = tools.getEnableTokenExpiredByIdApp(user.idapp);
|
const checkExpiry = tools.getEnableTokenExpiredByIdApp(user.idapp);
|
||||||
@@ -791,13 +836,13 @@ UserSchema.statics.findByTokenAnyAccess = function (token) {
|
|||||||
}).lean();
|
}).lean();
|
||||||
};
|
};
|
||||||
|
|
||||||
UserSchema.statics.findByCredentials = function (idapp, username, password, pwdcrypted) {
|
UserSchema.statics.findByCredentials = async function (idapp, username, password, pwdcrypted) {
|
||||||
const User = this;
|
const User = this;
|
||||||
let pwd = '';
|
let pwd = '';
|
||||||
|
|
||||||
let regexp = new RegExp(`^${username}$`, 'i');
|
let regexp = new RegExp(`^${username}$`, 'i');
|
||||||
|
|
||||||
return User.findOne({
|
let user = await User.findOne({
|
||||||
idapp,
|
idapp,
|
||||||
username: { $regex: regexp },
|
username: { $regex: regexp },
|
||||||
$or: [
|
$or: [
|
||||||
@@ -811,58 +856,46 @@ UserSchema.statics.findByCredentials = function (idapp, username, password, pwdc
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
||||||
}).then((user) => {
|
|
||||||
if (!user) {
|
|
||||||
// Check if with email:
|
|
||||||
return User.findOne({
|
|
||||||
idapp, email: username.toLowerCase(),
|
|
||||||
$or: [
|
|
||||||
{ deleted: { $exists: false } },
|
|
||||||
{ deleted: { $exists: true, $eq: false } }],
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return !user.deleted || (user.deleted && user.subaccount) ? user : null;
|
|
||||||
}
|
|
||||||
}).then((user) => {
|
|
||||||
if (!user) {
|
|
||||||
// Check with username telegram
|
|
||||||
return User.findOne({
|
|
||||||
idapp,
|
|
||||||
'profile.username_telegram': username.toLowerCase(),
|
|
||||||
$or: [
|
|
||||||
{ deleted: { $exists: false } },
|
|
||||||
{ deleted: { $exists: true, $eq: false } }],
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return !user.deleted || (user.deleted && user.subaccount) ? user : null;
|
|
||||||
}
|
|
||||||
}).then(user => {
|
|
||||||
if (!user)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
pwd = user.password;
|
|
||||||
|
|
||||||
if (pwdcrypted) {
|
|
||||||
if (pwd === user.password) {
|
|
||||||
return user;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
// Use bcrypt.compare to compare password and user.password
|
|
||||||
// console.log("pwd1 " + password);
|
|
||||||
// console.log("pwd2 " + pwd);
|
|
||||||
bcrypt.compare(password, pwd, (err, res) => {
|
|
||||||
if (res) {
|
|
||||||
resolve(user);
|
|
||||||
} else {
|
|
||||||
return resolve(null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
// Check if with email:
|
||||||
|
user = await User.findOne({
|
||||||
|
idapp, email: username.toLowerCase(),
|
||||||
|
$or: [
|
||||||
|
{ deleted: { $exists: false } },
|
||||||
|
{ deleted: { $exists: true, $eq: false } }],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
// Check with username telegram
|
||||||
|
user = await User.findOne({
|
||||||
|
idapp,
|
||||||
|
'profile.username_telegram': username.toLowerCase(),
|
||||||
|
$or: [
|
||||||
|
{ deleted: { $exists: false } },
|
||||||
|
{ deleted: { $exists: true, $eq: false } }],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!user) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
pwd = user.password;
|
||||||
|
|
||||||
|
if (pwdcrypted) {
|
||||||
|
if (pwd === user.password) {
|
||||||
|
return user;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await bcrypt.compare(password, pwd) ? user : null;
|
||||||
|
|
||||||
|
return res;
|
||||||
};
|
};
|
||||||
|
|
||||||
UserSchema.statics.findByUsername = async function (idapp, username, alsoemail, onlyifVerifiedByAportador) {
|
UserSchema.statics.findByUsername = async function (idapp, username, alsoemail, onlyifVerifiedByAportador) {
|
||||||
@@ -1885,6 +1918,7 @@ UserSchema.statics.getUserProfileByUsername = async function (
|
|||||||
|
|
||||||
if (perm === tools.Perm.PERM_NONE) {
|
if (perm === tools.Perm.PERM_NONE) {
|
||||||
whatToShow = {
|
whatToShow = {
|
||||||
|
idapp: 1,
|
||||||
lang: 1,
|
lang: 1,
|
||||||
index: 1,
|
index: 1,
|
||||||
username: 1,
|
username: 1,
|
||||||
@@ -1935,6 +1969,7 @@ UserSchema.statics.getUserProfileByUsername = async function (
|
|||||||
|
|
||||||
} else if (perm === tools.Perm.PERM_FRIEND) {
|
} else if (perm === tools.Perm.PERM_FRIEND) {
|
||||||
whatToShow = {
|
whatToShow = {
|
||||||
|
idapp: 1,
|
||||||
lang: 1,
|
lang: 1,
|
||||||
index: 1,
|
index: 1,
|
||||||
username: 1,
|
username: 1,
|
||||||
@@ -1984,6 +2019,7 @@ UserSchema.statics.getUserProfileByUsername = async function (
|
|||||||
|
|
||||||
} else if (perm === tools.Perm.PERM_ALL) {
|
} else if (perm === tools.Perm.PERM_ALL) {
|
||||||
whatToShow = {
|
whatToShow = {
|
||||||
|
idapp: 1,
|
||||||
lang: 1,
|
lang: 1,
|
||||||
index: 1,
|
index: 1,
|
||||||
username: 1,
|
username: 1,
|
||||||
@@ -3333,15 +3369,15 @@ UserSchema.statics.setCircuitCmd = async function (idapp, usernameOrig, circuitn
|
|||||||
await telegrambot.sendMsgTelegram(idapp, username_dest, msgDest);
|
await telegrambot.sendMsgTelegram(idapp, username_dest, msgDest);
|
||||||
|
|
||||||
msgerr = i18n.__('EXCEED_QTAMAX_MITTENTE', username_dest);
|
msgerr = i18n.__('EXCEED_QTAMAX_MITTENTE', username_dest);
|
||||||
await telegrambot.sendMsgTelegram(idapp, usernameOrig, msgDest);
|
await telegrambot.sendMsgTelegram(idapp, usernameOrig, msgerr);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.warn('🔴 ATTENZIONE! ', outres.errormsg + '\n(Mittente: ' + usernameOrig + ')');
|
console.warn('🔴 ATTENZIONE! ', outres.errormsg + '\n(Mittente: ' + usernameOrig + ')');
|
||||||
// await telegrambot.sendMsgTelegram(idapp, usernameOrig, msgOrig);
|
// await telegrambot.sendMsgTelegram(idapp, usernameOrig, msgOrig);
|
||||||
|
|
||||||
// Invia questo msg anche all'Admin
|
// Invia questo msg anche all'Admin
|
||||||
await telegrambot.sendMsgTelegramToTheAdmin(idapp, outres.errormsg + '\n(Mittente: ' + usernameOrig + ')', true);
|
await telegrambot.sendMsgTelegramToTheAdmin(idapp, outres.errormsg + '\n(Mittente: ' + usernameOrig + ')', true);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ((cmd === shared_consts.CIRCUITCMD.SENDCOINS_ACCEPT) || (cmd === shared_consts.CIRCUITCMD.SENDCOINS_REFUSE)) {
|
} else if ((cmd === shared_consts.CIRCUITCMD.SENDCOINS_ACCEPT) || (cmd === shared_consts.CIRCUITCMD.SENDCOINS_REFUSE)) {
|
||||||
@@ -6295,6 +6331,14 @@ UserSchema.statics.updateLastTimeAndUserAgent = async function (id, useragent) {
|
|||||||
|
|
||||||
return ris;
|
return ris;
|
||||||
}
|
}
|
||||||
|
UserSchema.statics.getMyGroupsById = async function (id) {
|
||||||
|
const User = this;
|
||||||
|
|
||||||
|
// cerca lo user by id e ritorna "profile.mygroups"
|
||||||
|
const ris = await User.findOne({ _id: id }, { 'profile.mygroups': 1 }).lean();
|
||||||
|
|
||||||
|
return ris;
|
||||||
|
};
|
||||||
UserSchema.statics.createNewSubRecord = async function (idapp, req) {
|
UserSchema.statics.createNewSubRecord = async function (idapp, req) {
|
||||||
const User = this;
|
const User = this;
|
||||||
|
|
||||||
|
|||||||
@@ -351,7 +351,6 @@ router.post('/:userId/ordercartstatus', authenticate, async function (req, res,
|
|||||||
let idapp = req.body.idapp;
|
let idapp = req.body.idapp;
|
||||||
let userId = req.params.userId;
|
let userId = req.params.userId;
|
||||||
let order_id = req.body.order_id;
|
let order_id = req.body.order_id;
|
||||||
const user = req.user;
|
|
||||||
let status = req.body.status;
|
let status = req.body.status;
|
||||||
let options = req.body.options;
|
let options = req.body.options;
|
||||||
|
|
||||||
@@ -403,7 +402,7 @@ router.post('/:userId/ordercartstatus', authenticate, async function (req, res,
|
|||||||
|
|
||||||
let orderscart = null;
|
let orderscart = null;
|
||||||
|
|
||||||
if (User.isManager(user.perm)) {
|
if (User.isManager(req.user.perm)) {
|
||||||
// Prende Tutti gli Ordini !
|
// Prende Tutti gli Ordini !
|
||||||
orderscart = await OrdersCart.getOrdersCartByUserId('ALL', idapp, 0, false);
|
orderscart = await OrdersCart.getOrdersCartByUserId('ALL', idapp, 0, false);
|
||||||
} else {
|
} else {
|
||||||
@@ -424,7 +423,6 @@ router.post('/:userId/ordercartstatus', authenticate, async function (req, res,
|
|||||||
//POST cart
|
//POST cart
|
||||||
router.post('/:userId/gestord', authenticate, async function (req, res, next) {
|
router.post('/:userId/gestord', authenticate, async function (req, res, next) {
|
||||||
let idapp = req.body.idapp;
|
let idapp = req.body.idapp;
|
||||||
const user = req.user;
|
|
||||||
let idGasordine = req.body.idGasordine;
|
let idGasordine = req.body.idGasordine;
|
||||||
|
|
||||||
const { User } = require('../models/user');
|
const { User } = require('../models/user');
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const i18n = require('i18n');
|
|||||||
|
|
||||||
const sharp = require('sharp');
|
const sharp = require('sharp');
|
||||||
|
|
||||||
const { authenticate, authenticate_noerror } = require(
|
const { authenticate, authenticate_noerror, authenticate_noerror_WithUser, authenticate_noerror_WithUserLean } = require(
|
||||||
'../middleware/authenticate');
|
'../middleware/authenticate');
|
||||||
|
|
||||||
const { ObjectId } = require('mongodb');
|
const { ObjectId } = require('mongodb');
|
||||||
@@ -1793,19 +1793,34 @@ router.post('/duprec/:table/:id', authenticate, async (req, res) => {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/loadsite/:userId/:idapp', authenticate_noerror, (req, res) => {
|
router.get('/loadsite/:userId/:idapp', authenticate_noerror_WithUserLean, (req, res) => {
|
||||||
load(req, res, '0');
|
load(req, res, '0');
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/loadsite/:userId/:idapp/:vers', authenticate_noerror,
|
router.get('/testpao', async (req, res) => {
|
||||||
async (req, res) => {
|
try {
|
||||||
|
// Simulazione di un'operazione asincrona (es. chiamata a DB o altro)
|
||||||
|
// await new Promise(resolve => setTimeout(resolve, 2000));
|
||||||
|
res.status(200).send('OK');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Errore durante il caricamento del sito:', error);
|
||||||
|
res.status(500).json({ error: 'Errore interno del server: TEST' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
router.get('/loadsite/:userId/:idapp/:vers', authenticate_noerror_WithUserLean, async (req, res) => {
|
||||||
|
try {
|
||||||
let versionstr = req.params.vers;
|
let versionstr = req.params.vers;
|
||||||
|
|
||||||
let version = tools.getVersionint(versionstr);
|
let version = tools.getVersionint(versionstr);
|
||||||
|
|
||||||
return await load(req, res, version);
|
return await load(req, res, version);
|
||||||
|
|
||||||
});
|
} catch (error) {
|
||||||
|
console.error('Errore durante il caricamento del sito:', error);
|
||||||
|
res.status(500).json({ error: 'Errore interno del server' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
async function load(req, res, version = '0') {
|
async function load(req, res, version = '0') {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ const _ = require('lodash');
|
|||||||
|
|
||||||
const reg = require('../reg/registration');
|
const reg = require('../reg/registration');
|
||||||
|
|
||||||
const { authenticate, authenticate_noerror } = require('../middleware/authenticate');
|
const { authenticate, authenticate_noerror, authenticate_withUser } = require('../middleware/authenticate');
|
||||||
|
|
||||||
|
|
||||||
const Cart = require('../models/cart');
|
const Cart = require('../models/cart');
|
||||||
@@ -55,13 +55,13 @@ const mongoose = require('mongoose').set('debug', false);
|
|||||||
|
|
||||||
const Subscription = require('../models/subscribers');
|
const Subscription = require('../models/subscribers');
|
||||||
|
|
||||||
function existSubScribe(userId, access, browser) {
|
async function existSubScribe(userId, access, browser) {
|
||||||
return Subscription.findOne({ userId, access, browser }).then(itemsub => {
|
try {
|
||||||
|
const itemsub = await Subscription.findOne({ userId, access, browser }).lean();
|
||||||
return itemsub;
|
return itemsub;
|
||||||
}).catch(err => {
|
} catch (err) {
|
||||||
return null;
|
return null;
|
||||||
});
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMobileComplete(user) {
|
function getMobileComplete(user) {
|
||||||
@@ -445,7 +445,6 @@ router.patch('/:id', authenticate, (req, res) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
router.post('/lastmovs', authenticate, async (req, res) => {
|
router.post('/lastmovs', authenticate, async (req, res) => {
|
||||||
const username = req.user ? req.user.username : '';
|
|
||||||
const nummov = req.body.nummov;
|
const nummov = req.body.nummov;
|
||||||
const idapp = req.body.idapp;
|
const idapp = req.body.idapp;
|
||||||
|
|
||||||
@@ -502,7 +501,6 @@ router.post('/profile', authenticate, (req, res) => {
|
|||||||
const perm = req.user ? req.user.perm : tools.Perm.PERM_NONE;
|
const perm = req.user ? req.user.perm : tools.Perm.PERM_NONE;
|
||||||
const username = req.body['username'];
|
const username = req.body['username'];
|
||||||
const idapp = req.body.idapp;
|
const idapp = req.body.idapp;
|
||||||
const locale = req.body.locale;
|
|
||||||
|
|
||||||
//++Todo: controlla che tipo di dati ha il permesso di leggere
|
//++Todo: controlla che tipo di dati ha il permesso di leggere
|
||||||
|
|
||||||
@@ -712,11 +710,10 @@ function checkBlocked(req, res, next) {
|
|||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
router.post('/login', checkBlocked, async (req, res) => {
|
||||||
router.post('/login', checkBlocked, (req, res) => {
|
const body = _.pick(req.body,
|
||||||
var body = _.pick(req.body,
|
|
||||||
['username', 'password', 'idapp', 'keyappid', 'lang']);
|
['username', 'password', 'idapp', 'keyappid', 'lang']);
|
||||||
var user = new User(body);
|
const userpass = new User(body);
|
||||||
// const subs = _.pick(req.body, ['subs']);
|
// const subs = _.pick(req.body, ['subs']);
|
||||||
|
|
||||||
// tools.mylog("LOG: u: " + user.username + " p:" + user.password);
|
// tools.mylog("LOG: u: " + user.username + " p:" + user.password);
|
||||||
@@ -728,135 +725,89 @@ router.post('/login', checkBlocked, (req, res) => {
|
|||||||
|
|
||||||
let resalreadysent = false;
|
let resalreadysent = false;
|
||||||
|
|
||||||
const myuser = user;
|
try {
|
||||||
|
const user = await User.findByCredentials(userpass.idapp, userpass.username, userpass.password);
|
||||||
|
|
||||||
return User.findByCredentials(user.idapp, user.username, user.password).
|
if (!user) {
|
||||||
then(async (user) => {
|
const rislogin = await User.tooManyLoginWrong(body.idapp, body.username, true);
|
||||||
// tools.mylog("CREDENZIALI ! ");
|
|
||||||
if (!user) {
|
|
||||||
|
|
||||||
const rislogin = await User.tooManyLoginWrong(body.idapp, body.username, true);
|
if (rislogin.troppilogin) {
|
||||||
if (rislogin.troppilogin) {
|
let text = 'Troppe richieste di Login ERRATE: ' + body.username + ' [IP: ' + tools.getiPAddressUser(req) + '] Tentativi: ' + rislogin.retry_pwd;
|
||||||
let text = 'Troppe richieste di Login ERRATE: ' + body.username + ' [IP: ' + tools.getiPAddressUser(req) + '] Tentativi: ' + rislogin.retry_pwd;
|
telegrambot.sendMsgTelegramToTheManagers(body.idapp, text);
|
||||||
telegrambot.sendMsgTelegramToTheManagers(body.idapp, text);
|
console.log('/login', text);
|
||||||
console.log('/login', text);
|
res.status(400).send({ code: server_constants.RIS_CODE_ERR, msg: text });
|
||||||
res.status(400).send({ code: server_constants.RIS_CODE_ERR, msg: text });
|
return;
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
await tools.snooze(3000);
|
await tools.snooze(2000);
|
||||||
|
|
||||||
if (!failedLoginAttempts[body.username]) {
|
if (!failedLoginAttempts[body.username]) {
|
||||||
failedLoginAttempts[body.username] = 1;
|
failedLoginAttempts[body.username] = 1;
|
||||||
} else {
|
} else {
|
||||||
failedLoginAttempts[body.username]++;
|
failedLoginAttempts[body.username]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
let numvolteerrati = failedLoginAttempts[body.username];
|
let numvolteerrati = failedLoginAttempts[body.username];
|
||||||
|
|
||||||
if (numvolteerrati > 2) {
|
if (numvolteerrati > 2) {
|
||||||
const msg = 'Tentativo (' + numvolteerrati + ') di Login ERRATO [' + body.username + ' , ' + ']\n' + '[IP: ' + tools.getiPAddressUser(req) + ']';
|
const msg = 'Tentativo (' + numvolteerrati + ') di Login ERRATO [' + body.username + ' , ' + ']\n' + '[IP: ' + tools.getiPAddressUser(req) + ']';
|
||||||
tools.mylogshow(msg);
|
tools.mylogshow(msg);
|
||||||
await telegrambot.sendMsgTelegramToTheAdmin(myuser.idapp, msg, true);
|
await telegrambot.sendMsgTelegramToTheAdmin(myuser.idapp, msg, true);
|
||||||
tools.writeErrorLog(msg);
|
tools.writeErrorLog(msg);
|
||||||
}
|
}
|
||||||
// telegrambot.sendMsgTelegramToTheManagers(body.idapp, msg);
|
|
||||||
|
|
||||||
if (failedLoginAttempts[body.username] >= MAX_FAILED_ATTEMPTS) {
|
if (failedLoginAttempts[body.username] >= MAX_FAILED_ATTEMPTS) {
|
||||||
blockUser(body.username);
|
blockUser(body.username);
|
||||||
text = 'Troppi tentativi di accesso falliti. Utente bloccato (' + body.username + ')' + ' [IP: ' + tools.getiPAddressUser(req) + ']';
|
text = 'Troppi tentativi di accesso falliti. Utente bloccato (' + body.username + ')' + ' [IP: ' + tools.getiPAddressUser(req) + ']';
|
||||||
tools.mylogshow(text);
|
tools.mylogshow(text);
|
||||||
telegrambot.sendMsgTelegramToTheManagers(req.body.idapp, text);
|
telegrambot.sendMsgTelegramToTheManagers(req.body.idapp, text);
|
||||||
res.status(403).json({ message: text });
|
res.status(403).json({ message: text });
|
||||||
resalreadysent = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.status(401).send({ code: server_constants.RIS_CODE_LOGIN_ERR });
|
|
||||||
resalreadysent = true;
|
resalreadysent = true;
|
||||||
|
|
||||||
}
|
}
|
||||||
return user;
|
|
||||||
}).
|
|
||||||
then(user => {
|
|
||||||
// console.log('Lgn-Ok');
|
|
||||||
if (user) {
|
|
||||||
return user.generateAuthToken(req).then((ris) => {
|
|
||||||
var usertosend = new User();
|
|
||||||
|
|
||||||
shared_consts.fieldsUserToChange().forEach((field) => {
|
res.status(401).send({ code: server_constants.RIS_CODE_LOGIN_ERR });
|
||||||
usertosend[field] = user[field];
|
resalreadysent = true;
|
||||||
});
|
}
|
||||||
|
|
||||||
// usertosend._id = user._id.toHexString();
|
|
||||||
// if (!User.isAdmin(req.user)) {
|
|
||||||
// usertosend.ipaddr = user.ipaddr;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// tools.mylog("user.verified_email:" + user.verified_email);
|
const myris = await user.generateAuthToken(req);
|
||||||
// tools.mylog("usertosend.userId", usertosend.userId);
|
|
||||||
|
|
||||||
return { usertosend, token: ris.token, refreshToken: ris.refreshToken };
|
const usertosend = new User();
|
||||||
|
|
||||||
}).then((myris) => {
|
shared_consts.fieldsUserToChange().forEach((field) => {
|
||||||
const access = 'auth';
|
usertosend[field] = user[field];
|
||||||
const browser = req.get('User-Agent');
|
|
||||||
|
|
||||||
// Check if already exist Subscribe
|
|
||||||
return existSubScribe(myris.usertosend._id, access, browser).
|
|
||||||
then(subscribe => {
|
|
||||||
return (subscribe !== null);
|
|
||||||
}).
|
|
||||||
then(subsExistonDb => {
|
|
||||||
// console.log('ESEGUITO OK')
|
|
||||||
return {
|
|
||||||
usertosend: myris.usertosend,
|
|
||||||
token: myris.token,
|
|
||||||
refreshToken: myris.refreshToken,
|
|
||||||
subsExistonDb,
|
|
||||||
};
|
|
||||||
}).
|
|
||||||
catch(err => {
|
|
||||||
return {
|
|
||||||
usertosend: myris.usertosend,
|
|
||||||
token: myris.token,
|
|
||||||
refreshToken: myris.refreshToken,
|
|
||||||
subsExistonDb: false,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}).then(myris => {
|
|
||||||
// console.log('res', myris.token, myris.usertosend);
|
|
||||||
|
|
||||||
// SEND TOKEN AND CODE RESULT
|
|
||||||
return res
|
|
||||||
.header('x-auth', myris.token)
|
|
||||||
.header('x-refrtok', myris.refreshToken)
|
|
||||||
.send({
|
|
||||||
usertosend: myris.usertosend,
|
|
||||||
code: server_constants.RIS_CODE_OK,
|
|
||||||
subsExistonDb: myris.subsExistonDb,
|
|
||||||
});
|
|
||||||
|
|
||||||
// tools.mylog("TROVATOOO!");
|
|
||||||
|
|
||||||
// tools.mylog('FINE LOGIN')
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).
|
|
||||||
catch((e) => {
|
|
||||||
console.error('ERRORE IN LOGIN: ' + e.message);
|
|
||||||
if (!resalreadysent)
|
|
||||||
res.status(400).
|
|
||||||
send({ code: server_constants.RIS_CODE_LOGIN_ERR_GENERIC, msgerr: e.message });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const subsExistonDb = await existSubScribe(usertosend._id, 'auth', req.get('User-Agent'));
|
||||||
|
|
||||||
|
res
|
||||||
|
.header('x-auth', myris.token)
|
||||||
|
.header('x-refrtok', myris.refreshToken)
|
||||||
|
.send({
|
||||||
|
usertosend,
|
||||||
|
code: server_constants.RIS_CODE_OK,
|
||||||
|
subsExistonDb,
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
console.error('ERRORE IN LOGIN: ' + e.message);
|
||||||
|
if (!resalreadysent)
|
||||||
|
res.status(400).
|
||||||
|
send({ code: server_constants.RIS_CODE_LOGIN_ERR_GENERIC, msgerr: e.message });
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
router.delete('/me/token', authenticate, (req, res) => {
|
router.delete('/me/token', authenticate_withUser, (req, res) => {
|
||||||
// tools.mylog("TOKENREM = " + req.token);
|
// tools.mylog("TOKENREM = " + req.token);
|
||||||
req.user.removeToken(req.token).then(() => {
|
try {
|
||||||
res.status(200).send();
|
req.user.removeToken(req.token).then(() => {
|
||||||
}, () => {
|
res.status(200).send();
|
||||||
res.status(400).send();
|
}, () => {
|
||||||
});
|
res.status(400).send();
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
console.log('delete(/me/token', e.message);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post('/setperm', authenticate, (req, res) => {
|
router.post('/setperm', authenticate, (req, res) => {
|
||||||
|
|||||||
@@ -754,19 +754,6 @@ connectToDatabase(connectionUrl, options)
|
|||||||
|
|
||||||
return { key: privateKey, cert: certificate };
|
return { key: privateKey, cert: certificate };
|
||||||
}
|
}
|
||||||
} else if (process.env.HTTPS_LOCALHOST === "true") {
|
|
||||||
try {
|
|
||||||
return {
|
|
||||||
key: fs.readFileSync(process.env.PATH_CERT_KEY, 'utf8'),
|
|
||||||
cert: fs.readFileSync(process.env.PATH_SERVER_CRT, 'utf8'),
|
|
||||||
ciphers: 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA384',
|
|
||||||
honorCipherOrder: true,
|
|
||||||
secureProtocol: 'TLSv1_2_method'
|
|
||||||
};
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Errore durante la lettura dei file di certificazione, error:', error.message);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Caso di default non specificato, potrebbe essere necessario aggiungere una gestione degli errori qui
|
// Caso di default non specificato, potrebbe essere necessario aggiungere una gestione degli errori qui
|
||||||
}
|
}
|
||||||
@@ -810,7 +797,7 @@ connectToDatabase(connectionUrl, options)
|
|||||||
let allowedOrigins = null;
|
let allowedOrigins = null;
|
||||||
|
|
||||||
if (!isProduction) {
|
if (!isProduction) {
|
||||||
allowedOrigins = 'http://localhost:3000';
|
allowedOrigins = 'https://localhost:3000';
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
allowedOrigins = domains.flatMap(domain => [
|
allowedOrigins = domains.flatMap(domain => [
|
||||||
@@ -819,11 +806,12 @@ connectToDatabase(connectionUrl, options)
|
|||||||
`https://test.${domain.hostname}`,
|
`https://test.${domain.hostname}`,
|
||||||
`https://testapi.${domain.hostname}`,
|
`https://testapi.${domain.hostname}`,
|
||||||
`https://freeplanet.app:3000`,
|
`https://freeplanet.app:3000`,
|
||||||
|
`https://freeplanet.app:3001`,
|
||||||
`http://${domain.hostname}`,
|
`http://${domain.hostname}`,
|
||||||
`http://api.${domain.hostname}`,
|
`http://api.${domain.hostname}`,
|
||||||
`http://test.${domain.hostname}`,
|
`http://test.${domain.hostname}`,
|
||||||
`http://testapi.${domain.hostname}`
|
`http://testapi.${domain.hostname}`
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -834,7 +822,8 @@ connectToDatabase(connectionUrl, options)
|
|||||||
try {
|
try {
|
||||||
// Validazione dell'input
|
// Validazione dell'input
|
||||||
if (!origin || typeof origin !== 'string' || !/^https?:\/\/[^\s/$.?#].[^\s]*$/.test(origin)) {
|
if (!origin || typeof origin !== 'string' || !/^https?:\/\/[^\s/$.?#].[^\s]*$/.test(origin)) {
|
||||||
console.error('❌ Origine non valida', origin);
|
if (origin)
|
||||||
|
console.error('❌ Origine non valida', origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Logging per il debug
|
// Logging per il debug
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
1.2.13
|
1.2.14
|
||||||
Reference in New Issue
Block a user