<%@ language = "JavaScript" %>
<% /*
     $Revision$
     $Id$

     File:          api_hmail.asp
     Description:   API voor opvangen van hMailserver e-mails

     Parameters:    Een xml
     Status:
     Context:       1-op-1 met \UTILS\mail_receive\EventHandlers.js
     Notes:         Deze API krijgen we XML binnen, en geven JSON terug.
                    Dat was het eenvoudigst
*/
    JSON_Result = true;
    THIS_FILE = "appl/api/api_hmail.asp";
%>
<!-- #include file="../Shared/common.inc" -->
<!-- #include file="../Shared/xml_converter.inc" -->
<!-- #include file="../Shared/flexfiles.inc" -->
<!-- #include file="../api/api.inc" -->
<!-- #include file="../aut/login.inc" -->
<%

var authparams = user.checkAutorisation("WEB_FACHML");
var API = new API_func();

function abortRejectMail(tekst, maillog, optionalColor)
{
    var result = { success: false,
                   message: tekst,
                   maillog: maillog||tekst
                 }
    __Log(result.maillog, optionalColor); // komt altijd ook in hmail log
    Response.Write(JSON.stringify(result));
    Response.End;
}

function stripHtml(html)
{
    html = (html||"");
    html = html.replace(/([=][\n])/g, "");  // Een = en crlf aan het einde is een afgebroken regel. Deze weer aan elkaar zetten.
    html = stripStyle(html);
    // verwijder html-tags
    html = html.replace(/(<br\s*\/?>)/ig,"\n\r");
    html = html.replace(/(<([^>]+)>)/ig,"");
    html = stripCharcodes(html);
    return html;
}

function stripStyle(html)
{
    html = (html||"");
    html = html.replace(/(<style[^<]*<\/style>)/igm, "");
    return html;
}

function stripCharcodes(html)
{
    html = (html||"");
    // Vervang lettercodes door het teken zelf.
    html = html.replace(/(&#x(\d|[a-f])+;)/ig
                    , function(a){
                            return String.fromCharCode(parseInt(a.substr(3,a.length-4), 16));
                        }
                    );
    html = html.replace(/(&nbsp;)/ig, " "); // &nbsp; naar spatie
    html = html.replace(/^[ \t]+/gm,"");    // verwijder leading spaces and tabs
    html = html.replace(/([\n\r])+/g,"\n"); // verwijder lege regels
    html = html.replace(/([\n\r]:)/g,":");  // zet een regel die begint met : maar achter de vorige
    return html;
}

function get_XMLval(psessionid, pxml, ptag, pindex)
{
    var tag_value = XMLval(pxml, ptag);
    var sql_ins = "INSERT INTO fac_result"
                + " (fac_result_sessionid, fac_result_naam, fac_result_waarde)"
                + " VALUES"
                + " (" + safe.quoted_sql(psessionid)
                + " ," + safe.quoted_sql(ptag + (pindex ? "_"+pindex : ""), 30) // Een mail kan meerdere bijlagen bevatten. Voor elke bijlage is er dan een filename en size.
                + " ," + safe.quoted_sql(tag_value, 4000)
                + " )";
    Oracle.Execute(sql_ins);
    return tag_value;
}

function getXml(xmlReq)
{
    var psession_id = Session.SessionID;
    // verwijder entries in de FAC_RESULT table zodat de action nieuwe resultaten kan schrijven
    var sql = "DELETE fac_result WHERE fac_result_sessionid = " + safe.quoted_sql(psession_id);
    Oracle.Execute(sql);

    var xmlParams = {
        sessionId:   psession_id,
        Subject:     get_XMLval(psession_id, xmlReq, "subject"),
        fromAddr:    get_XMLval(psession_id, xmlReq, "fromaddr"), // "Returns the address that the sender gave in the MAIL FROM SMTP-command."
        from:        get_XMLval(psession_id, xmlReq, "from"),     // "This property returns the content of the From MIME-header of the email."
        toAddr:      get_XMLval(psession_id, xmlReq, "to"),
        RecipientNr: get_XMLval(psession_id, xmlReq, "RecipientNr"), // 0 voor 1e recipient, soms 1 voor tweede
        htmlBody:    get_XMLval(psession_id, xmlReq, "htmlbody"),
        Body:        get_XMLval(psession_id, xmlReq, "body"),
        CC:          get_XMLval(psession_id, xmlReq, "CC"),
        originalto:  get_XMLval(psession_id, xmlReq, "originalto"),
        datum:       get_XMLval(psession_id, xmlReq, "Date"),
        emlpath:     get_XMLval(psession_id, xmlReq, "emlpath"),
        emlfile:     get_XMLval(psession_id, xmlReq, "emlfile"),
        emlsize:     get_XMLval(psession_id, xmlReq, "emlsize")
    };

    __Log("To: "       + xmlParams.toAddr);
    xmlParams.mailuser = xmlParams.toAddr.split("@")[0];

    return xmlParams;
}

function getPathParams(p_path, p_filename)
{   // kenmerkpath zal iets zijn met MLD\M1180___\M1180707\2803\
    // helaas hier weer terugparsen naar module, kenmerkkey en melding_key
    var path_params = {};
    var kenmerkpath = p_path;
    kenmerkpath = kenmerkpath.replace(/\\/g, "/"); // altijd forward slashed
    kenmerkpath = kenmerkpath.replace(/\/$/, "");  // laatste er af
    // Nu: MLD/M1180___/M1180707/2803
    var mm = kenmerkpath.match(/(.*)\/.*\/([A-Z])(\d+)\/(\d+)/);
    if (mm && mm.length == 5)
    {
        path_params = { kenmerkpath: kenmerkpath
                      , module: mm[1]
                      , niveau: mm[2]
                      , key: mm[3]
                      , kenmerk_key: mm[4]
                      };
        if (p_filename)
        {
            path_params.filename = p_filename;
            var digestpath = p_path + p_filename;
            __Log("digest van: "+digestpath);
            var oCrypto = new ActiveXObject("SLNKDWF.Crypto");
            path_params.digest = "NULL" //oCrypto.hex_sha1_file(digestpath); // geeft foutmelding !!
        }
    }
    return path_params;
}

function getEmailSetting(xmlReq, xmlParameters)
{
    function checkExpire(expireDate)
    {
        var expireResult = { success : true };
        if (expireDate != null)
        {
            var expire = new Date(expireDate);
            if (expire.getTime() < (new Date).getTime())
            {
                expireResult = { success: false,
                                 rejectMail: { tekst: L("lcl_fac_hmail_expired"),
                                               maillog: "Te laat, moest voor: " + expire
                                             }
                               };
            }
        }
        return expireResult;
    }

    function checkSender(emlSetting, xmlParameters)
    {
        var senderResult = { success: true };
        var theFrom = xmlParameters.fromAddr; // SMTP communicatie, werkt matig bij forwards
        if (emlSetting.fromMode == 1)
        {
            theFrom = xmlParameters.from; // uit email MIME-header
        }
        else if (emlSetting.fromMode == 2)
        {
            // example srs address: servicedesk+SRS=kWNyq=RW=manutan.nl=Paul.Gozeling@hsleiden.nl
            // output groups of RegExp:  1.	servicedesk 2.	kWNyq 3.	manutan.nl 4.	Paul.Gozeling
            // from e-mail address when SRS is detected: Paul.Gozeling@manutan.nl
            var regExpr  = RegExp("(.+)[+]SRS=(.+)[=].+=(.+)=(.+)[@]");
            if (regExpr.test(xmlParameters.fromAddr)) // test whether the xmlParameters.fromAddr is a SRS address
                theFrom = regExpr.exec(xmlParameters.fromAddr)[4] + "@" + regExpr.exec(xmlParameters.fromAddr)[3]; // concat (group-4 @ group-3) as the xmlParameters.fromAddr
        }

        var shouldFrom = emlSetting.from;
        if (shouldFrom)
        {
            if (String(shouldFrom).toUpperCase() != String(theFrom).toUpperCase())
            {
                senderResult = { success: false,
                                 rejectMail: { tekst: L("lcl_fac_hmail_wrong_sender").format(theFrom),
                                               maillog: "Foute afzender. Verwacht: " + shouldFrom + ", kreeg: " + theFrom
                                             }
                               };
            }
        }
        senderResult.theFrom = theFrom;
        return senderResult;
    }

    // Check the subject against general rules (emlSetting null) or some defined
    // regular expression from the configuration in emlSetting
    // return .success true if the subject is okay, false else
    // If false, a reason is given in .message
    function checkSubject(emlSetting, xmlParameters)
    {
        var subjectResult = { success: true };
        if (emlSetting == null)
        {
            // generieke onderwerpcheck tegen rubbish
            var v_subject_undeliverable = new RegExp(S("mail_subject_undeliverable")).test(xmlParameters.Subject);
            var v_subject_ignore = new RegExp(S("mail_subject_ignore")).test(xmlParameters.Subject);
            var senderResult = null;
            if (v_subject_undeliverable || v_subject_ignore)
            {
                subjectResult.success = false;
                subjectResult.message = ( v_subject_undeliverable ? S("mail_subject_undeliverable") : S("mail_subject_ignore"));
            }
        } else {
            // matcht het mailonderwerp wellicht met een specifieke configuratie?
            if (emlSetting.text)
            {
                subjectResult.success = new RegExp(emlSetting.text, "ig").test(xmlParameters.Subject);
                subjectResult.message = "Subject " + xmlParameters.Subject + (subjectResult.success ? " matches " : " does not match ") + emlSetting.text
                __Log(subjectResult.message);
            }
            else // geen voorwaarde is altijd goed
                subjectResult.success = true;
        }
        return subjectResult;
    }

    function setPath(attachpath)
    {
        var path = attachpath;
        if (path && path.substr(0,1) == "@") // @/?API=OPDR_VO&APIKEY=**** zet automatisch de huidige url ervoor
        {
            path = HTTP.urlzelf() + path.substr(1);
        }

        if (path && path.substr(0, 1) == "*") // Bijvoorbeeld '*flexfilespath'
        {
            path = S(path.substr(1)) + "/";
        }
        return path;
    }

    var result = {};
    var sql = "SELECT fac_email_setting_key,"
            + "       fac_email_setting_volgnr,"
            + "       fac_email_setting_action,"
            + "       fac_email_setting_expire,"
            + "       fac_email_setting_from,"          // optioneel: waar de afzender aan moet voldoen
            + "       fac_email_setting_frommode,"
            + "       fac_email_setting_text,"          // optioneel: waar het onderwerp aan moet voldoen
            + "       fac_email_setting_attachpath,"
            + "       fac_email_setting_attachext,"
            + "       fac_email_setting_reqattachext,"  // optioneel: extensie van de bijlage die verplicht is
            + "       fac_email_setting_attachmaxkb,"
            + "       fac_email_setting_loglevel,"
            + "       prs_perslid_key_auth"
            + "  FROM fac_email_setting"
            + " WHERE upper(fac_email_setting_user) = UPPER("+safe.quoted_sql(xmlParameters.mailuser)+")"
            + " ORDER BY fac_email_setting_volgnr";

            // Als je het zo zou doen vind je organischer de meest specifieke match, met volgnummer slechts beslissend als er meerdere zouden zijn
            // Het lijkt echter safer om datr aan de gebruiker over te laten en die dat met volgnummer expliciet te kunnen laten definieren.
            //+ " ORDER BY fac_email_setting_reqattachext NULLS LAST, fac_email_setting_from NULLS LAST, fac_email_setting_text NULLS LAST, fac_email_setting_volgnr";

    var oRs = Oracle.Execute(sql);
    if (oRs.eof)
    {   // Er is geen fac_email_setting record gevonden.
        result.rejectMail = { emlVolgnr: -1,
                              tekst: L("lcl_fac_hmail_unknown_user").format(xmlParameters.mailuser),
                              maillog: "E-mail user niet ontvankelijk: " + xmlParameters.mailuser,
                              optionalColor: "#ff4"
                            };
    }
    else
    {   // Er bestaat minimaal 1 fac_email_setting record voor deze ontvanger.
        var allowedSetting = {};
        var rejectedAttach = [];
        var hasRequiredAttachment = false;
        var hasMatchingFrom       = false;
        var hasMatchingSubject    = false;

        // Loop door de fac_email_setting records en bepaal welke het beste past bij deze e-mail
        // Dat is de eerste match op basis van het volgnummer, waarbij de 3 criteria niet conflicteren.
        // - de afzender matcht of is niet specifiek gedefinieerd
        // - het onderwerp matcht de conditie of is niet specifiek gedefinieerd
        // - de verplichte bijlage is present of is niet specifiek gedefinieerd
        // Het gevonden record levert de aan te roepen mailprocessor en 
        // (bij de default fac.processemail) de aan te maken standaardmelding

        while (!oRs.eof && !(hasRequiredAttachment && hasMatchingFrom && hasMatchingSubject))
        {
            var emlSetting = {
                key:                    oRs("fac_email_setting_key").Value,
                volgnr:                 oRs("fac_email_setting_volgnr").Value,
                action:                 oRs("fac_email_setting_action").Value, // Package aanroep
                expire:                 oRs("fac_email_setting_expire").Value,
                allowed_attachext:      oRs("fac_email_setting_attachext").Value,
                required_attachext:     oRs("fac_email_setting_reqattachext").Value,
                prs_perslid_key_auth:   oRs("prs_perslid_key_auth").Value,
                attachpath:             oRs("fac_email_setting_attachpath").Value,
                attach_maxkb:           oRs("fac_email_setting_attachmaxkb").Value,
                fromMode:               oRs("fac_email_setting_frommode").Value,
                from:                   oRs("fac_email_setting_from").Value,
                text:                   oRs("fac_email_setting_text").Value,
                loglevel:               oRs("fac_email_setting_loglevel").Value
            };
            emlSetting.path = setPath(emlSetting.attachpath);
            __Log("Scanning e-mail setting: "+emlSetting.key + " (volgnr "+emlSetting.volgnr+")");

            var expireResult  = checkExpire(emlSetting.expire);
            var senderResult  = checkSender(emlSetting, xmlParameters);
            var subjectResult = checkSubject(emlSetting, xmlParameters);
            
            hasMatchingFrom    = senderResult.success;
            hasMatchingSubject = subjectResult.success;
            __Log('hasMatchingFrom '+ hasMatchingFrom);
            __Log('hasMatchingSubject '+ hasMatchingSubject);

            // als fron en subject okay zijn, dan kijken we of er een verplicht kenmerk is
            if (expireResult.success && hasMatchingFrom && hasMatchingSubject)
            {
                emlSetting.theFrom = senderResult.theFrom;  // verbeter na de uitgevoerde controle
                var attachResult = checkAttach(xmlReq, xmlParameters, emlSetting);
                emlSetting.allowedFiles = attachResult.allowedFiles;
                emlSetting.requiredFound = attachResult.requiredFound;
                hasRequiredAttachment = emlSetting.required_attachext == null || attachResult.requiredFound;
                allowedSetting = emlSetting;
                if (attachResult.rejectedFiles.tekst != "")
                {
                    result.rejectMail = attachResult.rejectedFiles;
                }
                else
                {
                    delete result.rejectMail;
                }
            }
            else
            {
                if (!allowedSetting.allowedFiles)
                {
                    result.rejectMail = (!expireResult.success ? expireResult.rejectMail : senderResult.rejectMail);
                }
            }
            __Log("hasRequiredAttachment: " + hasRequiredAttachment);
            oRs.MoveNext();
        }
        __Log("Done looking for matching e-mail settings");
        result.emlSetting = allowedSetting;
        result.silentignoreemail = checkSubject(null, xmlParameters).message;
    }
    oRs.Close();
    return result;
}

function emailAction(emlSetting, xmlParam, resultParam)
{
    var result = resultParam || {};
    var path = result.path;
    if (emlSetting.action) // Bijv "fac.processemail" of "uwva.closeorder-sample"
    {
        if (!xmlParam.Body || xmlParam.Body == "") // Voorkeur voor plaintekst
        {
            var v_body = L("lcl_fac_hmail_empty_body") + stripHtml(xmlParam.htmlBody);
        }
        else
        {
            var v_body = xmlParam.Body;
        }

        var actionsql =
              "BEGIN " + emlSetting.action + " (" + safe.quoted_sql(emlSetting.theFrom)     + ","
                                                  + safe.quoted_sql(xmlParam.toAddr)      + ","
                                                  + safe.quoted_sql(xmlParam.Subject || L("lcl_fac_hmail_no_subject"))  + "," // de actions kunnen slecht tegen lege subject
                                                  + "?, "
                                                  + safe.quoted_sql(xmlParam.sessionId) + ","
                                                  + emlSetting.key + ");"
            + "END;";

        var oparams = [ { typ: adLongVarChar, dir: adParamInput, val: v_body.substr(0, S("mld_melding_oms_maxlen")==4000?3990:S("mld_melding_oms_maxlen")) } ];
        Oracle.ExecuteParam(actionsql, oparams);

        // Nog iets specifieks terug te melden voor de logging?
        var sql = "SELECT fac_result_waarde"
                + "  FROM fac_result"
                + " WHERE fac_result_naam = 'maillog'"
                + "   AND fac_result_sessionid = " + safe.quoted_sql(xmlParam.sessionId);
        var oRs = Oracle.Execute(sql);
        if (!oRs.Eof)
        {
           result.maillog = oRs("fac_result_waarde").Value;
        }
        else
        {
           result.maillog = "E-mail afgehandeld via: " + emlSetting.action;
        }
        oRs.Close();

        var sql = "SELECT fac_result_waarde"
                + "  FROM fac_result"
                + " WHERE fac_result_naam = 'errormsg'"
                + "   AND fac_result_sessionid = " + safe.quoted_sql(xmlParam.sessionId);
        var oRs = Oracle.Execute(sql);
        if (!oRs.Eof)
        {
            if (__Logging == 0)
            {
                __DoLog(actionsql);
            }
            __DoLog(oRs("fac_result_waarde").Value, '#ff00ff');
            __DoLog("E-mail is gebounced naar afzender met bovenstaande foutmelding.");
            // De meeste process_email procedures schrijven zo'n error ook wel met fac.writelog ('PROCESSEMAIL') weg
            // Dat wil ik graag ook in de gewone logging terugzien voor eenvoudiger troubleshooten
            // Ik heb geen methode om gegarandeerd het goede record op te zoeken dus pak gewoon
            // de laatste in de afgelopen minuut
            var sql = "SELECT *"
                    + "  FROM (  SELECT imp_log_datum, imp_log_omschrijving, imp_log_hint"
                    + "            FROM imp_log"
                    + "           WHERE imp_log_applicatie = 'PROCESSEMAIL'"
                    + "             AND imp_log_datum > SYSDATE - 1/24/60" // afgelopen minuut
                    + "        ORDER BY imp_log_key DESC)"
                    + " WHERE ROWNUM = 1"
            var oRs2 = Oracle.Execute(sql);
            if (!oRs2.Eof)
            {
                __DoLog("Uit imp_log (heeft hoogstwaarschijnlijk betrekking op deze mail)\n--\n"
                       + "{0} {1}\n{2}".format(toDateTimeString(oRs2("imp_log_datum").Value, true),
                                                                oRs2("imp_log_omschrijving").Value,
                                                                oRs2("imp_log_hint").Value));
            }
            oRs2.Close();

            result.rejectMail = { tekst: oRs("fac_result_waarde").Value,
                                  maillog: result.maillog
                                };
        }
        oRs.Close();

        if (!result.rejectMail)
        {
            var sql = "SELECT fac_result_waarde"
                    + "  FROM fac_result"
                    + " WHERE fac_result_naam = 'kenmerkpath'"
                    + "   AND fac_result_sessionid = " + safe.quoted_sql(xmlParam.sessionId);
            var oRs = Oracle.Execute(sql);
            if (!oRs.Eof)
            {
               result.kenmerkpath = oRs("fac_result_waarde").Value;
               result.path = path + oRs("fac_result_waarde").Value;
            }
            oRs.Close();

            var sql = "SELECT fac_result_waarde"
                    + "  FROM fac_result"
                    + " WHERE fac_result_naam = 'kenmerkorgmailpath'"
                    + "   AND fac_result_sessionid = " + safe.quoted_sql(xmlParam.sessionId);
            var oRs = Oracle.Execute(sql);
            if (!oRs.Eof)
            {
               result.eml_kenmerkpath = oRs("fac_result_waarde").Value;
               result.original_mail_path = path + oRs("fac_result_waarde").Value;
               result.original_mail_file = "email "+toISODateTimeString(Date.parse(xmlParam.datum)).replace(/:/g,"_") + ".eml";
            }
            oRs.Close();
        }
    }
    else
    {
        result.maillog = "Verder geen database process_email actie gedefinieerd";
    }

    return result;
}

// 
function checkAttach(xmlReq, xmlParameter, emlSetting)
{
    var requiredFound = false;
    var allowedFiles = [];
    var rejectedFiles = { tekst: [], maillog: []};

    var Attachments = xmlReq.getElementsByTagName("attachment");
    for (var i=0; i < Attachments.length; i++)
    {
        var safefilename = safe.filename(XMLval(Attachments[i], "filename", i));
        var extension = safefilename.substr(safefilename.lastIndexOf("."));
        var attsize = parseInt(XMLval(Attachments[i], "size", i), 10);
        if (emlSetting.attach_maxkb && emlSetting.attach_maxkb > 0) {
            var filesize_MB = (attsize / 1024 / 1024).toFixed(3);           // attsize is in bytes. Maak er MB van.
            var maxsize_MB = (emlSetting.attach_maxkb / 1024).toFixed(3);   // attach_maxkb in in kB. Maak er MB van.
        }
        if (safefilename == S("fac_logo_file"))
        {   // Waarschijnlijk een FACILITOR bon gereply'd
            __Log("Bijlage {0} genegeerd.".format(safefilename));
        }
        else if (attsize < S("flex_min_size")) // sowieso te klein
        {
            __Log("Bijlage {0} genegeerd, te klein met {1} bytes.".format(safefilename, attsize));
        }
        else if (attsize < S("flex_min_imgsize") && new RegExp(S("flex_min_imgsize_ext"), "ig").test(safefilename)) // plaatje te klein (facebook, twitter, X)
        {
            __Log("Plaatje {0} genegeerd, te klein met {1} bytes.".format(safefilename, attsize));
        }
        else if (   emlSetting.attach_maxkb && emlSetting.attach_maxkb > 0  // Er is een maximum bestandsgrootte ingesteld
                 && parseFloat(filesize_MB) > parseFloat(maxsize_MB))       // En die is overschreden
        {
            __Log(L("fac_email_setting_err1").format(safefilename, filesize_MB, maxsize_MB));
            rejectedFiles.tekst.push(L("fac_email_setting_err1").format(safefilename, filesize_MB, maxsize_MB));
            rejectedFiles.maillog.push(("Bijlage {0} te groot: {1} bytes").format(safefilename, attsize));
        }
        else if (!new RegExp(S("flexallowedext"), "ig").test(safefilename))
        {   // Niet ondersteunde bestandstype
            __Log("Onbekende extensie e-mail bijlage: {0} ({1} bytes) van {2}. Bestand is niet opgeslagen.".format(safefilename, attsize, emlSetting.theFrom));
        }
        else if (emlSetting.allowed_attachext && !new RegExp(emlSetting.allowed_attachext, "ig").test(safefilename))
        {   // bestand is niet van het opgegeven type
            __Log("Ongewenste extensie e-mail bijlage: {0} ({1} bytes) van {2}. Bestand is niet opgeslagen.".format(safefilename, attsize, emlSetting.theFrom));
        }
        else
        {
            allowedFiles.push( { sequence: i,
                                 safefilename: safefilename,
                                 attsize: attsize
                               });
            if (new RegExp(emlSetting.required_attachext, "ig").test(safefilename)) {
                requiredFound = true;
            }
        }
    }

    var attachResult = { requiredFound: requiredFound,
                         allowedFiles: allowedFiles,
                         rejectedFiles: { tekst: rejectedFiles.tekst.join("\n"),
                                          maillog: rejectedFiles.maillog.join("\n"),
                                          optionalColor: "#ff4"
                                        }
                       };
    return attachResult;
}

function saveAttachments(xmlReq, emlSetting, xmlParam, resultParam)
{
    var result = resultParam || {};
    result.headers = result.headers || {};

    // Als we een bijlage van een zekere type verwachten kan er beter maar een zijn ook!
    if ((emlSetting.allowed_attachext || emlSetting.required_attachext) && !emlSetting.allowedFiles.length)
    {
        var msg = "Vreemd: ik had eigenlijk een '{0}' bijlage verwacht van {1}".format( (emlSetting.required_attachext ? emlSetting.required_attachext : emlSetting.allowed_attachext), emlSetting.theFrom);
        result.rejectMail = { tekst: L("lcl_fac_hmail_no_attachment"),
                              maillog: msg,
                              optionalColor: "#ff4"
                            };
    }
    else
    {
        var isUrl = false;
        if (result.path && (result.path.substr(0,5) == "http:" || result.path.substr(0,6) == "https:"))
        {
            isUrl = true;
            result.path = result.path.format(safe.url(emlSetting.theFrom), safe.url(xmlParam.toAddr), safe.url(xmlParam.Subject));
            // supports &from={0}&to={1}&subject={2}
            // bij de echte aanroep wordt &filename={filename} nog ingevuld met de echte filenaam
            var fso = Server.CreateObject("Scripting.FileSystemObject");
            if (!fso.FolderExists(result.tempfolder))
                fso.CreateFolder(result.tempfolder);
        }


        // opruimen
        var sql = "DELETE fac_result WHERE fac_result_sessionid = " + safe.quoted_sql(xmlParam.sessionId);
        Oracle.Execute(sql);

        var safeFiles = [];
        if (result.path)
        {
            // Als de url &multifile=1 bevat wordt niet per file een aanroep gedaan met de file in de body maar
            // worden alle files in de temp-folder verzameld en dan wordt er één aanroep van de url gedaan
            // met alleen de temp filenamen in de body
            result.isMulti = result.path.indexOf("multifile=1") > -1;
            if (result.isMulti)
            {
                __Log("Alle bijlagen straks naar " + result.path);
                // Dit gaat allemaal in de http-body naar result.path
                result.headers["Content-Type"] = "application/json";
                result.headers["Accept"] = "application/json";
                result.emlSetting = emlSetting; // de e-mail settings uit de database
                result.mailParams = xmlParam;   // alles wat we maar weten van de e-mail
                if (emlSetting.prs_perslid_key_auth) // per bestand/url unieke jwt
                {
                    var jwt = getBearerToken(emlSetting.prs_perslid_key_auth, "_INTERNAL", 30);
                    result.headers["Authorization"] = "Bearer " + jwt;
                }
            }
            var Attachments = emlSetting.allowedFiles;
            for (var i=0; i < Attachments.length; i++)
            {
                var filesequence = Attachments[i].sequence; // Let op: Deze sequence wordt gebruikt \\Utils\mail_receive\EventHandlers.js
                                                            //         Het is de volgorde zoals bestanden in de mail staan.
                                                            //         De bestanden die je niet nodig hebt staan daar ook nog!
                var safefilename = Attachments[i].safefilename;
                var attsize = Attachments[i].attsize;
                if (isUrl)
                {
                    if (result.isMulti)
                        var txt = '{0} bijlage ({1} bytes)'.format(safefilename, attsize);
                    else
                        txt = '{0} bijlage ({1} bytes) verwerken met {2}'.format(safefilename, attsize, result.path);
                    var tempfilename = result.tempfolder + "\\API_HMAIL_" + shared.random(32) + "_" + safefilename;
                    __Log(txt + '\n' + 'Tijdelijk bewaard onder {0}'.format(tempfilename));
                    var safefile = { sequence: filesequence,
                                     safefilename: safefilename,
                                     tempfilename: tempfilename,
                                     extension: safefilename.substr(safefilename.lastIndexOf(".")+1),
                                     safeurl: result.path,
                                     headers: {}
                                   };
                    if (emlSetting.prs_perslid_key_auth) // per bestand/url unieke jwt
                    {
                        // Omdat de bestanden sequentieel worden verwekt door hMailserver kan het een tijdje duren
                        // voordat de laatste aan de beurt is. Daarom timeout (veel) groter dan 30 seconde zetten.
                        var jwt = getBearerToken(emlSetting.prs_perslid_key_auth, "_INTERNAL", 300); // of: (i+1)*30 maar dat is overdreven
                        safefile.headers["Authorization"] = "Bearer " + jwt;
                    }
                    safeFiles.push (safefile);
                }
                else
                {
                    if (emlSetting.attachpath == "*flexfilespath" && result.kenmerkpath)
                    {   // Dan ook alvast registreren in fac_bijlagen.
                        var path_params = getPathParams(result.kenmerkpath);
                        if (path_params.module) // Als module bestaat zijn alle parameters aanwezig.
                        {
                            var sql = "BEGIN "
                                    + "  flx.setflexbijlage"
                                            + "(" + safe.quoted_sql(path_params.module)
                                            + ", " + path_params.kenmerk_key
                                            + ", " + path_params.key
                                            + ", " + safe.quoted_sql(path_params.kenmerkpath)
                                            + ", " + "NULL"
                                            + ", " + safe.quoted_sql(safefilename)
                                            + ", " + attsize
                                            + ", " + "SYSDATE"
                                            + ", " + "NULL" // Helaas (nog) zonder digest omdat we het bestand nog niet hebben
                                            + ");"
                                    + " END;";
                            Oracle.Execute(sql);
                        }
                        else
                        {
                            __DoLog("Strange, could not properly decode flexfiles path " + result.kenmerkpath, "#f00");
                        }
                    }
                    __Log("{0} bijlage ({1} bytes) mag naar {2}".format(safefilename, attsize, result.path));
                    CreateFullPath(result.path); // Hoeft hMailserver dat niet meer te doen. Eist wel dat hMail op 'onze' webserver draait
                    safeFiles.push ({ sequence: filesequence,
                                      safefilename: result.path + safefilename,
                                      extension: safefilename.substr(safefilename.lastIndexOf(".")+1)
                                    });
                }
            }
        }
        result.attachments = safeFiles;
    }
    return result;
}

function saveEml(xmlParams, params)
{
    if (params.original_mail_path)
    {   // Sla ook het email bestand als een bijlage op.
        // Eventuele bijlagen worden uit het email bestand verwijderd in EventHandlers.js
        CreateFullPath(params.original_mail_path);
        var path_params = getPathParams(params.eml_kenmerkpath, params.original_mail_file);
        if (path_params.module) // Als module bestaat zijn alle parameters aanwezig.
        {
            var sql = "BEGIN "
                    + "  flx.setflexbijlage"
                    + "( " + safe.quoted_sql(path_params.module)
                    + ", " + path_params.kenmerk_key
                    + ", " + path_params.key
                    + ", " + safe.quoted_sql(path_params.kenmerkpath)
                    + ", " + "NULL"
                    + ", " + safe.quoted_sql(path_params.filename)
                    + ", " + xmlParams.emlsize
                    + ", " + "SYSDATE"
                    + ", " + "NULL" //safe.quoted_sql(path_params.digest)
                    + ");"
                    + " END;";
            Oracle.Execute(sql);
        }
        else
        {
            __DoLog("Strange, could not properly decode flexfiles path for original file: " + params.eml_kenmerkpath, "#f00");
        }
    }
}


// *********************************************************
// puur intern gebruik dus geen stylesheet conversie nodig
var parsed = RequestXML(API);
if (parsed.error)
{
     abortRejectMail("Error " + parsed.error);
}
var xmlReq = parsed.xml;
var xmlParameters = getXml(xmlReq);
var emlResult = getEmailSetting(xmlReq, xmlParameters);

if (emlResult.emlSetting && !emlResult.rejectMail)
{
    var emlSetting = emlResult.emlSetting;
    if (emlSetting.loglevel > 0)
    {
       __Logging = emlSetting.loglevel || __Logging || 0; // GLOBAL: Voor de rest van dit bestand
    }

    __Log("Subject: "     + xmlParameters.Subject);
    __Log("From: "        + xmlParameters.from);
    __Log("FromAddr: "    + xmlParameters.fromAddr);
    __Log("To: "          + xmlParameters.toAddr);
    __Log("RecipientNr: " + xmlParameters.RecipientNr);
    __Log("htmlBody: "    + xmlParameters.htmlBody);
    __Log("body: "        + xmlParameters.Body);
    __Log("E-mail user ontvankelijk: " + xmlParameters.mailuser);
    __Log("gebruikt email setting: " + emlSetting.key);

    if (emlResult.silentignoreemail)
    {
        var saveResult = { silentignoreemail : true, maillog: "Ignored because subject matches " + emlResult.silentignoreemail }
        __Log("Ignored because subject matches " + emlResult.silentignoreemail);
    }
    else
    {
        var  result = { success: true,
                        path: emlSetting.path,
                        kenmerkpath: "",
                        attachments: [],
                        tempfolder: shared.tempFolder(),
                        loglevel: emlSetting.loglevel || 0
                       };

        var actionResult = emailAction(emlSetting, xmlParameters, result);
        if (!actionResult.rejectMail)
        {
            var saveResult = saveAttachments(xmlReq, emlSetting, xmlParameters, actionResult);
            if (!saveResult.rejectMail)
            {
                saveEml(xmlParameters, saveResult);
            }
            else
            {
                emlResult.rejectMail = saveResult.rejectMail;
            }
        }
        else
        {
            emlResult.rejectMail = actionResult.rejectMail;
        }
    }
}

if (emlResult.rejectMail)
{
    abortRejectMail(emlResult.rejectMail.tekst, emlResult.rejectMail.maillog, emlResult.rejectMail.optionalColor);
}

Response.Write(JSON.stringify(saveResult));
%>
<% ASPPAGE_END(); %>
