groton-school / knowledgebase

Knowledgebase website
https://kb.groton.org
GNU General Public License v3.0
0 stars 0 forks source link

this path formatting is wonky #43

Closed github-actions[bot] closed 1 month ago

github-actions[bot] commented 1 month ago

https://github.com/groton-school/knowledgebase/blob/fa99cc68e5464aa46491f32b59f89f5684ad47b3/apps/router/src/Handlers/Factories/CloudStorageRouter.ts#L90


    );
  }
  return async (req, res) => {
    try {
      if (await Auth.authorize(req, res)) {
        const bucket = new Storage({
          authClient: Auth.authClient,
          projectId: process.env.GOOGLE_CLOUD_PROJECT
        }).bucket(config.storage.bucket);

        let reqPath = path.join(
          req.path.substring(1),
          /\.\w+$/.test(req.path) ? '' : 'index.html'
        );
        const acl = await new ACL(req, res, groups).prepare();
        const gsPath = `gs://${config.storage.bucket}/${reqPath}`;
        const reqFile = index.find(
          (f) => f.index.uri.includes(gsPath) && acl.hasAccess(f.permissions)
        );
        let success = false;

        if (reqFile) {
          const file = bucket.file(reqPath);
          const metadata = (await file.getMetadata())[0];
          res.type(metadata.contentType || path.extname(reqPath));
          const stream = file.createReadStream();
          stream.on('data', (data) => res.write(data));
          stream.on('error', (error) =>
            Logger.error(file.cloudStorageURI.href, error)
          );
          stream.on('end', () => res.end());
          success = true;
        } else {
          reqPath = req.path.replace(/^\/(.+[^\/])\/?$/, '$1');
          const requestedDir = index.find(
            (f) => f.index.path == reqPath && acl.hasAccess(f.permissions)
          );
          if (requestedDir) {
            const pages = index
              .filter(
                (file) =>
                  file.parents?.includes(requestedDir.id) &&
                  acl.hasAccess(file.permissions)
              )
              .sort((a, b) => a.name.localeCompare(b.name));
            // TODO template
            res.send(`<!doctype html>
                    <html lang="en">
                    <head>
                      <meta charset="utf-8">
                      <meta name="viewport" content="width=device-width, initial-scale=1">
                      <meta content="text/html; charset=UTF-8" http-equiv="content-type">
                      <meta item-prop="kb.id" content="${requestedDir.id}">
                      <title>${requestedDir.name}</title>${
              config.ui?.site?.favicon
                ? `
                      <link rel="icon" href="${config.ui.site.favicon}">`
                : ''
            }${
              config.ui?.site?.css
                ? `
                      <link rel="stylesheet" href="${config.ui.site.css}" />`
                : ''
            }
                    </head>
                    <body>
                    <div id="directory">
                    <h1 class="title">${requestedDir.name}</h1>
                    ${pages
                      .map(
                        (page) =>
                          `<div class="page">
                            <div class="name"><a href="/${
                              // TODO this path formatting is wonky
                              page.index.path
                            }/">${page.name}</a></div>${
                            page.description
                              ? `<div class="description">${page.description}</div>`
                              : ''
                          }</div>`
                      )
                      .join('')}
                    </div>${
                      config.ui?.site?.js
                        ? `
                      <script src="${config.ui.site.js}"></script>`
                        : ''
                    }
                    </body>
                    `);
            success = true;
          }
        }
        if (!success) {
          res.send(404);
        }
      }
    } catch (error) {
      if (error == 'Error: No refresh token is set.') {
        // silent login if refresh token not present
        // TODO this should be caught/handled in Auth.authorize, not here
        req.session.redirect = req.url.replace(`https://${req.host}`, '');
        res.redirect(Auth.authUrl);
      } else {
        Logger.error(req.originalUrl, {
          function: 'CloudStorageRouter',
          error
        });
        res.status((error as any).code || 500);
      }
    }
  };
battis commented 1 month ago

whatevs