From 0b2fff1b0ca83b57b318ec94f33e6dd5842630c4 Mon Sep 17 00:00:00 2001 From: acanas Date: Tue, 29 Nov 2022 18:37:45 +0100 Subject: [PATCH] =?UTF-8?q?Version=2022.60:=20=20=20=20Nov=2029,=202022=20?= =?UTF-8?q?=20Fixed=20bug=20sending=20notification=20emails.=20Reported=20?= =?UTF-8?q?by=20Manuel=20Rodr=C3=ADguez=20=C3=81lvarez=20and=20Eva=20Mart?= =?UTF-8?q?=C3=ADnez=20Ortigosa.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- swad_browser_database.c | 8 ++++++-- swad_browser_size.c | 1 + swad_changelog.h | 3 ++- swad_mail.c | 38 ++++++++++++++++++++++++++++---------- swad_mail.h | 8 ++++++-- swad_mail_database.c | 2 +- swad_notification.c | 41 +++++++++++++++++++++++++++-------------- swad_password.c | 13 ++++++++++--- 8 files changed, 81 insertions(+), 33 deletions(-) diff --git a/swad_browser_database.c b/swad_browser_database.c index e23ca8b72..6ba26c4ea 100644 --- a/swad_browser_database.c +++ b/swad_browser_database.c @@ -290,7 +290,9 @@ unsigned Brw_DB_GetFileMetadataByPath (MYSQL_RES **mysql_res,const char *Path) " WHERE FileBrowser=%u" " AND Cod=%ld" " AND ZoneUsrCod=%ld" - " AND Path='%s'", + " AND Path='%s'" + " ORDER BY FilCod DESC" // Due to errors, there could be old entries for the same path. + " LIMIT 1", // Select the most recent entry. (unsigned) Brw_DB_FileBrowserForDB_files[Gbl.FileBrowser.Type], Cod, ZoneUsrCod, @@ -2311,7 +2313,9 @@ unsigned Brw_DB_CheckIfFileOrFolderIsSetAsHiddenUsingPath (MYSQL_RES **mysql_res " WHERE FileBrowser=%u" " AND Cod=%ld" " AND ZoneUsrCod=%ld" - " AND Path='%s'", + " AND Path='%s'" + " ORDER BY FilCod DESC" // Due to errors, there could be old entries for the same path. + " LIMIT 1", // Select the most recent entry. (unsigned) Brw_DB_FileBrowserForDB_files[Gbl.FileBrowser.Type], Cod, ZoneUsrCod, diff --git a/swad_browser_size.c b/swad_browser_size.c index 56ef4e1aa..9ead576d5 100644 --- a/swad_browser_size.c +++ b/swad_browser_size.c @@ -26,6 +26,7 @@ /*****************************************************************************/ #include // For scandir, etc. +#include // For free #include // For string functions #include // For lstat diff --git a/swad_changelog.h b/swad_changelog.h index c214d80c3..266835e83 100644 --- a/swad_changelog.h +++ b/swad_changelog.h @@ -604,7 +604,7 @@ TODO: Fix bug: error al enviar un mensaje a dos recipientes, error on duplicate TODO: Attach pdf files in multimedia. */ -#define Log_PLATFORM_VERSION "SWAD 22.59.1 (2022-11-23)" +#define Log_PLATFORM_VERSION "SWAD 22.60 (2022-11-29)" #define CSS_FILE "swad22.57.1.css" #define JS_FILE "swad22.49.js" /* @@ -615,6 +615,7 @@ Que al subir un fichero por defecto est Al subir cosas para los grupos, en documentos, resltar más los grupos porque no son conscientes... Exportar listas en CSV. + Version 22.60: Nov 29, 2022 Fixed bug sending notification emails. Reported by Manuel Rodríguez Álvarez and Eva Martínez Ortigosa. (334114 lines) Version 22.59.1: Nov 23, 2022 Fixed bug in file browser. Reported by Javier Fernández Baldomero. (334070 lines) Version 22.59: Nov 06, 2022 New module swad_browser_size. (334067 lines) Version 22.58: Nov 06, 2022 New module swad_action_list for list of actions. (333958 lines) diff --git a/swad_mail.c b/swad_mail.c index c20935472..9037866b0 100644 --- a/swad_mail.c +++ b/swad_mail.c @@ -326,12 +326,20 @@ bool Mai_CheckIfUsrCanReceiveEmailNotif (const struct Usr_Data *UsrDat) { char MailDomain[Cns_MAX_BYTES_EMAIL_ADDRESS + 1]; - /***** Check #1: is my email address confirmed? *****/ + /***** Check #1: is email empty or filled? *****/ + if (!UsrDat->Email[0]) + return false; + + /***** Check #2: is email address confirmed? *****/ if (!UsrDat->EmailConfirmed) return false; - /***** Check #2: if my mail domain allowed? *****/ + /***** Check #3: check if there is mail domain *****/ Mai_GetMailDomain (UsrDat->Email,MailDomain); + if (!MailDomain[0]) + return false; + + /***** Check #4: is mail domain allowed? *****/ return Mai_DB_CheckIfMailDomainIsAllowedForNotif (MailDomain); } @@ -1454,15 +1462,21 @@ bool Mai_SendMailMsgToConfirmEmail (void) extern const char *Txt_There_was_a_problem_sending_an_email_automatically; char FileNameMail[PATH_MAX + 1]; FILE *FileMail; + Lan_Language_t ToUsrLanguage; const char *UniqueNameEncrypted = Cry_GetUniqueNameEncrypted (); int ReturnCode; /***** Create temporary file for mail content *****/ Mai_CreateFileNameMail (FileNameMail,&FileMail); + /***** If I have no language, set language to current language *****/ + ToUsrLanguage = Gbl.Usrs.Me.UsrDat.Prefs.Language; + if (ToUsrLanguage == Lan_LANGUAGE_UNKNOWN) + ToUsrLanguage = Gbl.Prefs.Language; + /***** Write mail content into file and close file *****/ /* Welcome note */ - Mai_WriteWelcomeNoteEMail (FileMail,&Gbl.Usrs.Me.UsrDat); + Mai_WriteWelcomeNoteEMail (FileMail,&Gbl.Usrs.Me.UsrDat,ToUsrLanguage); /* Store encrypted key in database */ Mai_InsertMailKey (Gbl.Usrs.Me.UsrDat.Email,UniqueNameEncrypted); @@ -1475,13 +1489,14 @@ bool Mai_SendMailMsgToConfirmEmail (void) Cfg_URL_SWAD_CGI); /* Footer note */ - Mai_WriteFootNoteEMail (FileMail,Gbl.Prefs.Language); + Mai_WriteFootNoteEMail (FileMail,ToUsrLanguage); fclose (FileMail); /***** Call the script to send an email *****/ ReturnCode = Mai_SendMailMsg (FileNameMail, - Txt_Confirmation_of_your_email_NO_HTML); + Txt_Confirmation_of_your_email_NO_HTML, + Gbl.Usrs.Me.UsrDat.Email); /***** Remove temporary file *****/ unlink (FileNameMail); @@ -1609,15 +1624,16 @@ void Mai_CreateFileNameMail (char FileNameMail[PATH_MAX + 1],FILE **FileMail) /************ Write a welcome note heading the automatic email ***************/ /*****************************************************************************/ -void Mai_WriteWelcomeNoteEMail (FILE *FileMail,struct Usr_Data *UsrDat) +void Mai_WriteWelcomeNoteEMail (FILE *FileMail,const struct Usr_Data *UsrDat, + Lan_Language_t ToUsrLanguage) { extern const char *Txt_Dear_NO_HTML[Usr_NUM_SEXS][1 + Lan_NUM_LANGUAGES]; extern const char *Txt_user_NO_HTML[Usr_NUM_SEXS][1 + Lan_NUM_LANGUAGES]; fprintf (FileMail,"%s %s:\n", - Txt_Dear_NO_HTML[UsrDat->Sex][UsrDat->Prefs.Language], + Txt_Dear_NO_HTML[UsrDat->Sex][ToUsrLanguage], UsrDat->FrstName[0] ? UsrDat->FrstName : - Txt_user_NO_HTML[UsrDat->Sex][UsrDat->Prefs.Language]); + Txt_user_NO_HTML[UsrDat->Sex][ToUsrLanguage]); } /*****************************************************************************/ @@ -1731,7 +1747,9 @@ static void Mai_EditingMailDomainDestructor (void) // Return 0 on success // Return != 0 on error -int Mai_SendMailMsg (char FileNameMail[PATH_MAX + 1],const char *Subject) +int Mai_SendMailMsg (const char FileNameMail[PATH_MAX + 1], + const char *Subject, + const char ToEmail[Cns_MAX_BYTES_EMAIL_ADDRESS + 1]) { char Command[2048 + Cfg_MAX_BYTES_SMTP_PASSWORD + @@ -1747,7 +1765,7 @@ int Mai_SendMailMsg (char FileNameMail[PATH_MAX + 1],const char *Subject) Cfg_AUTOMATIC_EMAIL_SMTP_PORT, Cfg_AUTOMATIC_EMAIL_FROM, Cfg_GetSMTPPassword (), - Gbl.Usrs.Me.UsrDat.Email, + ToEmail, Cfg_PLATFORM_SHORT_NAME,Subject, FileNameMail); ReturnCode = system (Command); diff --git a/swad_mail.h b/swad_mail.h index db92079ae..b4dbb658e 100644 --- a/swad_mail.h +++ b/swad_mail.h @@ -27,6 +27,7 @@ /********************************* Headers ***********************************/ /*****************************************************************************/ +#include "swad_constant.h" #include "swad_user.h" /*****************************************************************************/ @@ -94,11 +95,14 @@ bool Mai_SendMailMsgToConfirmEmail (void); void Mai_ConfirmEmail (void); void Mai_CreateFileNameMail (char FileNameMail[PATH_MAX + 1],FILE **FileMail); -void Mai_WriteWelcomeNoteEMail (FILE *FileMail,struct Usr_Data *UsrDat); +void Mai_WriteWelcomeNoteEMail (FILE *FileMail,const struct Usr_Data *UsrDat, + Lan_Language_t ToUsrLanguage); void Mai_WriteFootNoteEMail (FILE *FileMail,Lan_Language_t Language); bool Mai_ICanSeeOtherUsrEmail (const struct Usr_Data *UsrDat); -int Mai_SendMailMsg (char FileNameMail[PATH_MAX + 1],const char *Subject); +int Mai_SendMailMsg (const char FileNameMail[PATH_MAX + 1], + const char *Subject, + const char ToEmail[Cns_MAX_BYTES_EMAIL_ADDRESS + 1]); #endif diff --git a/swad_mail_database.c b/swad_mail_database.c index 35fd18d85..45f047dc2 100644 --- a/swad_mail_database.c +++ b/swad_mail_database.c @@ -90,7 +90,7 @@ unsigned Mai_DB_GetEmailFromUsrCod (MYSQL_RES **mysql_res,long UsrCod) { return (unsigned) DB_QuerySELECT (mysql_res,"can not get email address", - "SELECT E_mail," // row[0] + "SELECT E_mail," // row[0] "Confirmed" // row[1] " FROM usr_emails" " WHERE UsrCod=%ld" diff --git a/swad_notification.c b/swad_notification.c index 3ad347c70..12cb62fe7 100644 --- a/swad_notification.c +++ b/swad_notification.c @@ -296,7 +296,9 @@ static Act_Action_t Ntf_StartFormGoToAction (Ntf_NotifyEvent_t NotifyEvent, const struct For_Forums *Forums); static void Ntf_PutHiddenParamNotifyEvent (Ntf_NotifyEvent_t NotifyEvent); -static void Ntf_SendPendingNotifByEMailToOneUsr (struct Usr_Data *ToUsrDat,unsigned *NumNotif,unsigned *NumMails); +static void Ntf_SendPendingNotifByEMailToOneUsr (const struct Usr_Data *ToUsrDat, + unsigned *NumNotif, + unsigned *NumMails); static void Ntf_GetNumNotifSent (long DegCod,long CrsCod, Ntf_NotifyEvent_t NotifyEvent, unsigned *NumEvents,unsigned *NumMails); @@ -1204,7 +1206,7 @@ void Ntf_SendPendingNotifByEMailToAllUsrs (void) MYSQL_RES *mysql_res; unsigned NumUsrs; unsigned NumUsr; - struct Usr_Data UsrDat; + struct Usr_Data ToUsrDat; unsigned NumNotif; unsigned NumTotalNotif = 0; unsigned NumMails; @@ -1214,7 +1216,7 @@ void Ntf_SendPendingNotifByEMailToAllUsrs (void) if ((NumUsrs = Ntf_DB_GetUsrsWhoMustBeNotified (&mysql_res))) { /***** Initialize structure with user's data *****/ - Usr_UsrDataConstructor (&UsrDat); + Usr_UsrDataConstructor (&ToUsrDat); /***** Notify the users one by one *****/ for (NumUsr = 0; @@ -1222,22 +1224,22 @@ void Ntf_SendPendingNotifByEMailToAllUsrs (void) NumUsr++) { /* Get next user */ - UsrDat.UsrCod = DB_GetNextCode (mysql_res); + ToUsrDat.UsrCod = DB_GetNextCode (mysql_res); /* Get user's data */ - if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&UsrDat, // Get user's data from database - Usr_DONT_GET_PREFS, + if (Usr_ChkUsrCodAndGetAllUsrDataFromUsrCod (&ToUsrDat, // Get user's data from database + Usr_GET_PREFS, // User's language necessary to write email Usr_DONT_GET_ROLE_IN_CURRENT_CRS)) { /* Send one email to this user */ - Ntf_SendPendingNotifByEMailToOneUsr (&UsrDat,&NumNotif,&NumMails); + Ntf_SendPendingNotifByEMailToOneUsr (&ToUsrDat,&NumNotif,&NumMails); NumTotalNotif += NumNotif; NumTotalMails += NumMails; } } /***** Free memory used for user's data *****/ - Usr_UsrDataDestructor (&UsrDat); + Usr_UsrDataDestructor (&ToUsrDat); } /***** Free structure that stores the query result *****/ @@ -1251,7 +1253,9 @@ void Ntf_SendPendingNotifByEMailToAllUsrs (void) /************ Send pending notifications of one user by email ****************/ /*****************************************************************************/ -static void Ntf_SendPendingNotifByEMailToOneUsr (struct Usr_Data *ToUsrDat,unsigned *NumNotif,unsigned *NumMails) +static void Ntf_SendPendingNotifByEMailToOneUsr (const struct Usr_Data *ToUsrDat, + unsigned *NumNotif, + unsigned *NumMails) { extern const char *Txt_NOTIFY_EVENTS_There_is_a_new_event_NO_HTML[1 + Lan_NUM_LANGUAGES]; extern const char *Txt_NOTIFY_EVENTS_There_are_X_new_events_NO_HTML[1 + Lan_NUM_LANGUAGES]; @@ -1290,13 +1294,13 @@ static void Ntf_SendPendingNotifByEMailToOneUsr (struct Usr_Data *ToUsrDat,unsig /***** If user has no language, set it to current language *****/ ToUsrLanguage = ToUsrDat->Prefs.Language; if (ToUsrLanguage == Lan_LANGUAGE_UNKNOWN) - ToUsrLanguage = Gbl.Prefs.Language; + ToUsrLanguage = Cfg_DEFAULT_LANGUAGE; /***** Create temporary file for mail content *****/ Mai_CreateFileNameMail (FileNameMail,&FileMail); /***** Welcome note *****/ - Mai_WriteWelcomeNoteEMail (FileMail,ToUsrDat); + Mai_WriteWelcomeNoteEMail (FileMail,ToUsrDat,ToUsrLanguage); if (NumNtfs == 1) fprintf (FileMail,Txt_NOTIFY_EVENTS_There_is_a_new_event_NO_HTML[ToUsrLanguage], Cfg_PLATFORM_SHORT_NAME); @@ -1315,6 +1319,13 @@ static void Ntf_SendPendingNotifByEMailToOneUsr (struct Usr_Data *ToUsrDat,unsig { /* Get next event */ row = mysql_fetch_row (mysql_res); + /* row[0]: NotifyEvent + row[1]: FromUsrCod + row[2]: InsCod + row[3]: CtrCod + row[4]: DegCod + row[5]: CrsCod + row[6]: Cod */ /* Get event type (row[0]) */ NotifyEvent = Ntf_GetNotifyEventFromStr (row[0]); @@ -1325,7 +1336,7 @@ static void Ntf_SendPendingNotifByEMailToOneUsr (struct Usr_Data *ToUsrDat,unsig Usr_DONT_GET_PREFS, Usr_DONT_GET_ROLE_IN_CURRENT_CRS); - /* Get institution code (row[2]), + /* Get insti. code (row[2]), center code (row[3]), degree code (row[4]), course code (row[5]) */ @@ -1417,7 +1428,8 @@ static void Ntf_SendPendingNotifByEMailToOneUsr (struct Usr_Data *ToUsrDat,unsig /***** Call the command to send an email *****/ ReturnCode = Mai_SendMailMsg (FileNameMail, - Txt_Notifications_NO_HTML[ToUsrLanguage]); + Txt_Notifications_NO_HTML[ToUsrLanguage], + ToUsrDat->Email); /***** Remove temporary file *****/ unlink (FileNameMail); @@ -1429,7 +1441,8 @@ static void Ntf_SendPendingNotifByEMailToOneUsr (struct Usr_Data *ToUsrDat,unsig *NumMails = 1; /* Update statistics about notifications */ - Ntf_UpdateNumNotifSent (Hie.Deg.DegCod,Hie.Crs.CrsCod,NotifyEvent,*NumNotif,*NumMails); + Ntf_UpdateNumNotifSent (Hie.Deg.DegCod,Hie.Crs.CrsCod,NotifyEvent, + *NumNotif,*NumMails); } /***** Mark all pending notifications of this user as 'sent' *****/ diff --git a/swad_password.c b/swad_password.c index 646492ebd..051ff0d2f 100644 --- a/swad_password.c +++ b/swad_password.c @@ -405,6 +405,7 @@ int Pwd_SendNewPasswordByEmail (char NewRandomPlainPassword[Pwd_MAX_BYTES_PLAIN_ extern const char *Txt_New_password_NO_HTML[1 + Lan_NUM_LANGUAGES]; char FileNameMail[PATH_MAX + 1]; FILE *FileMail; + Lan_Language_t ToUsrLanguage; int ReturnCode; /***** Create temporary file for mail content *****/ @@ -413,9 +414,14 @@ int Pwd_SendNewPasswordByEmail (char NewRandomPlainPassword[Pwd_MAX_BYTES_PLAIN_ /***** Create a new random password *****/ Pwd_CreateANewPassword (NewRandomPlainPassword); + /***** If I have no language, set language to current language *****/ + ToUsrLanguage = Gbl.Usrs.Me.UsrDat.Prefs.Language; + if (ToUsrLanguage == Lan_LANGUAGE_UNKNOWN) + ToUsrLanguage = Gbl.Prefs.Language; + /***** Write mail content into file and close file *****/ /* Welcome note */ - Mai_WriteWelcomeNoteEMail (FileMail,&Gbl.Usrs.Me.UsrDat); + Mai_WriteWelcomeNoteEMail (FileMail,&Gbl.Usrs.Me.UsrDat,ToUsrLanguage); /* Message body */ fprintf (FileMail,Txt_The_following_password_has_been_assigned_to_you_to_log_in_X_NO_HTML, @@ -424,13 +430,14 @@ int Pwd_SendNewPasswordByEmail (char NewRandomPlainPassword[Pwd_MAX_BYTES_PLAIN_ Gbl.Usrs.Me.UsrDat.Email); /* Footer note */ - Mai_WriteFootNoteEMail (FileMail,Gbl.Prefs.Language); + Mai_WriteFootNoteEMail (FileMail,ToUsrLanguage); fclose (FileMail); /***** Call the script to send an email *****/ ReturnCode = Mai_SendMailMsg (FileNameMail, - Txt_New_password_NO_HTML[Gbl.Usrs.Me.UsrDat.Prefs.Language]); + Txt_New_password_NO_HTML[ToUsrLanguage], + Gbl.Usrs.Me.UsrDat.Email); /***** Remove temporary file *****/ unlink (FileNameMail);