Announcement

Collapse
No announcement yet.

Protecting Non-Product Downloads

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Protecting Non-Product Downloads

    Store owner needs to protect the download of certain documents for logged-in and ‘approved’ customers only. I had first suggested making them a free download product, but there was concern that the customer might not go through the bother of ordering the document.

    I reached out to Miva Support and was given something that "Claude" had written:

    Step 1 — Move the PDFs out of the web root
    Move your PDFs to the Miva data directory, which is not web-accessible. For example:
    /data/secured-docs/2026/Pricelist_2026.pdf
    This folder is readable by MivaScript via file_read() but has no public URL.

    Step 2 — Create a secure download page template
    Add a new page (e.g. screen code DLDOC) with a .mvt template. This page:

    Checks that the customer is logged in (g.Customer_ID)
    Optionally checks they are in an "approved" customer group
    Reads the PDF from the data directory
    Streams it back to the browser with the correct headers

    Code:
    <mvt:comment> Redirect to login if not authenticated </mvt:comment>
    <mvt:if expr="NOT g.Customer_ID">
    <mvt:assign name="g.redirect" value="miva_output_header( 'Location', g.secure_sessionurl $ 'Screen=LOGN' )" />
    <mvt:exit />
    </mvt:if>
    
    <mvt:comment> Whitelist of allowed files - never trust raw user input for a path </mvt:comment>
    <mvt:assign name="l.allowed_files:1" value="'2026/Pricelist_2026.pdf'" />
    <mvt:assign name="l.allowed_count" value="1" />
    
    <mvt:comment> Validate the requested file against the whitelist </mvt:comment>
    <mvt:assign name="l.file_valid" value="0" />
    <mvt:assign name="l.pos" value="1" />
    <mvt:while expr="l.pos LE l.allowed_count">
    <mvt:if expr="g.file EQ l.allowed_files[l.pos]">
    <mvt:assign name="l.file_valid" value="1" />
    </mvt:if>
    <mvt:assign name="l.pos" value="l.pos + 1" />
    </mvt:while>
    
    <mvt:if expr="NOT l.file_valid">
    <mvt:assign name="g.h" value="miva_output_header( 'HTTP/1.1', '403 Forbidden' )" />
    <mvt:exit />
    </mvt:if>
    
    <mvt:comment> Read the PDF from the secured data directory </mvt:comment>
    <mvt:assign name="l.filepath" value="'secured-docs/' $ g.file" />
    <mvt:assign name="l.result" value="file_read( l.filepath, 'data', l.pdf_data )" />
    
    <mvt:if expr="l.result EQ -1">
    <mvt:assign name="g.h" value="miva_output_header( 'HTTP/1.1', '404 Not Found' )" />
    <mvt:exit />
    </mvt:if>
    
    <mvt:comment> Stream the PDF to the browser </mvt:comment>
    <mvt:assign name="g.h" value="miva_output_header( 'Content-Type', 'application/pdf' )" />
    <mvt:assign name="g.h" value="miva_output_header( 'Content-Disposition', 'attachment; filename=&quot;' $ glosub( g.file, '/', '_' ) $ '&quot;' )" />
    <mvt:assign name="g.h" value="miva_output_header( 'Cache-Control', 'no-cache, no-store, must-revalidate' )" />
    <mvt:assign name="g.h" value="miva_output_header( 'Pragma', 'no-cache' )" />
    <mvt:assign name="g.h" value="miva_output_header( 'Expires', '0' )" />
    <mvt:eval expr="l.pdf_data" />
    Step 3 — Link to the download page
    Replace your old PDF links with URLs like:
    https://www.store.com/mm5/merchant.m...elist_2026.pdf
    Logged-out customers hitting this URL get bounced to the login screen. Logged-in customers get the PDF streamed directly to them.
    When I tested the code, the only thing the link would do was bounce to the login screen, even if I was logged in.

    Also, I noticed that there wasn't any way to verify the "group" (probably because I had not mentioned that the "group" is a Custom Customer Field). I had other questions too, but I figured I'll save them until after I can get this snippet to work for the one file.

    Has anyone done something like this?
    Leslie Kirk
    Miva Certified Developer
    Miva Merchant Specialist since 1997
    Previously of Webs Your Way
    (aka Leslie Nord leslienord)

    Email me: [email protected]
    www.lesliekirk.com

    Follow me: X | Facebook | Pinterest

    #2
    If the customer needs to be "Approved" you could use availability groups. I do this for downloadable documents/brochures that are only available to wholesale customers.

    Create a product then using a custom field and some template code create a button on the product page to download the docs. Customers can also purchase the item, at $0.00, and they include a printed bundle of 25 in the order.

    You could do the same thing using a category assigned to an availability group. Just add all the download links and info to the category header.
    Ron Frigon
    Jedi Webmaster Obi-Ron Kenobi

    Comment


      #3
      Originally posted by Ron Frigon View Post
      If the customer needs to be "Approved" you could use availability groups. I do this for downloadable documents/brochures that are only available to wholesale customers.

      Create a product then using a custom field and some template code create a button on the product page to download the docs. Customers can also purchase the item, at $0.00, and they include a printed bundle of 25 in the order.

      You could do the same thing using a category assigned to an availability group. Just add all the download links and info to the category header.
      Thanks, Ron, this site has used the established method for eons now. It might be difficult to "convert". Also, the product method had already been discussed and nixed.

      Now if there were some way to make it an instant download without having to go through the rigmarole of going through checkout, then it would be perfect...
      Last edited by lesliekirk; 06-18-26, 04:11 AM.
      Leslie Kirk
      Miva Certified Developer
      Miva Merchant Specialist since 1997
      Previously of Webs Your Way
      (aka Leslie Nord leslienord)

      Email me: [email protected]
      www.lesliekirk.com

      Follow me: X | Facebook | Pinterest

      Comment

      Working...
      X