Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(download): import to bookshelf from a link with an opdf authwall from the downloader service (opds, cli, ...) #2733

Merged
merged 7 commits into from
Jan 6, 2025

Conversation

panaC
Copy link
Member

@panaC panaC commented Dec 20, 2024

See #2512 (comment)

close and replace #2732

@panaC
Copy link
Member Author

panaC commented Dec 20, 2024

Tested with https://github.com/panaC/opds2-auth-test-server on localhost:8282

with this patch :

git diff src/pub-feed/pub-feed.service.ts
diff --git a/src/pub-feed/pub-feed.service.ts b/src/pub-feed/pub-feed.service.ts
index 218a364..7bda904 100644
--- a/src/pub-feed/pub-feed.service.ts
+++ b/src/pub-feed/pub-feed.service.ts
@@ -111,6 +111,19 @@ export class PubFeedService {
             const pubsNotFiltered = await Promise.all(pubsPromise);
             const pubs = pubsNotFiltered.filter((v) => !!v);
 
+            {
+                const pub = new OPDSPublication();
+                const meta = new OPDSMetadata();
+                meta.Title = "test";
+
+                pub.Metadata = meta;
+
+                pub.AddLink_("http://localhost:3000", "application/epub+zip", "http://opds-spec.org/acquisition/open-access", "");
+
+                pubs.push(pub);
+            }
+
+
             console.log("pubs loaded");
 
             feed.Publications = pubs;

And with this basic authentication http file server on localhost:3000 :

const http = require('http');
const fs = require('fs');
const path = require('path');

const publicationPath = path.join(__dirname, 'childrens-literature.epub'); // Path to your publication file
const authUsername = 'admin';
const authPassword = 'admin';

const server = http.createServer((req, res) => {
  // Check for Authorization header
  const authHeader = req.headers.authorization;
  if (!authHeader || !authHeader.startsWith('Basic ')) {
    // Return 401 with OPDS authentication JSON
    res.statusCode = 401;
    res.setHeader('Content-Type', 'application/opds-authentication+json');
    res.end(JSON.stringify({
      "title": "basic auth",
      "id": "",
      "links": [
        {
          "type": "image/jpeg",
          "rel": "logo",
          "href": "https://www.edrlab.org/wp-content/uploads/2016/12/[email protected]"
        }
      ],
      "authentication": [
        {
          "type": "http://opds-spec.org/auth/basic",
          "labels": {
            "login": "LOGIN",
            "password": "PASSWORD"
          }
        }
      ],
      "err": null,
      "info": "Basic realm=\"login\""
    }));
    console.log("not authHeader", authHeader);
    return;
  }

  // Extract credentials from Authorization header
  const credentials = Buffer.from(authHeader.substring(6), 'base64').toString('utf8').split(':');
  const username = credentials[0];
  const password = credentials[1];

  // Verify credentials
  if (username !== authUsername || password !== authPassword) {
    // Return 401 with OPDS authentication JSON
    res.statusCode = 401;
    res.setHeader('Content-Type', 'application/opds-authentication+json');
    res.end(JSON.stringify({
      "title": "basic auth",
      "id": "",
      "links": [
        {
          "type": "image/jpeg",
          "rel": "logo",
          "href": "https://www.edrlab.org/wp-content/uploads/2016/12/[email protected]"
        }
      ],
      "authentication": [
        {
          "type": "http://opds-spec.org/auth/basic",
          "labels": {
            "login": "LOGIN",
            "password": "PASSWORD"
          }
        }
      ],
      "err": null,
      "info": "Basic realm=\"login\""
    }));
    console.log("not admin:admin", username, password);
    return;
  }

  // Serve the publication file if authenticated
  res.setHeader('Content-Type', 'application/epub+zip');
  fs.createReadStream(publicationPath).pipe(res);
});

server.listen(3000, () => {
  console.log('Server running on port 3000');
});

@danielweck
Copy link
Member

This works great with a private OPDS feed located behind a VPN (cannot share here), merging this PR now.
Thank you very much @panaC :)

@danielweck danielweck merged commit 87d078e into develop Jan 6, 2025
8 checks passed
@danielweck danielweck deleted the fix/importFromLink-with-authentication branch January 6, 2025 11:14
@danielweck
Copy link
Member

I filed a separate issue for the LCP JSON ZIP injection regression bug:
#2746

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants