Преглед изворни кода

WIP: implement validateReferer

Yuki Takei пре 2 година
родитељ
комит
71d5a5312e

+ 59 - 3
apps/app/src/server/middlewares/certify-shared-file/validate-referer.spec.ts

@@ -1,7 +1,30 @@
 import { validateReferer } from './validate-referer';
 
+const mocks = vi.hoisted(() => {
+  return {
+    configManagerMock: {
+      getConfig: vi.fn(),
+    },
+  };
+});
+
+vi.mock('~/server/service/config-manager', () => {
+  return { configManager: mocks.configManagerMock };
+});
+
 describe('validateReferer', () => {
 
+  it('throw a parse error when the siteUrl is invalid', () => {
+    // setup
+    mocks.configManagerMock.getConfig.mockImplementation(() => {
+      return 'invalid siteUrl string';
+    });
+
+    // when
+    const refererString = 'referer string';
+    expect(() => validateReferer(refererString)).toThrowError();
+  });
+
   describe('refurns false', () => {
 
     it('when the referer argument is undefined', () => {
@@ -10,16 +33,49 @@ describe('validateReferer', () => {
 
       // then
       expect(result).toBeFalsy();
+      expect(mocks.configManagerMock.getConfig).not.toHaveBeenCalled(); // getConfig have not been called
+    });
+
+    it('when the siteUrl is not set', () => {
+      // setup
+      mocks.configManagerMock.getConfig.mockImplementation(() => {
+        return null;
+      });
+
+      // when
+      const refererString = 'referer string';
+      const result = validateReferer(refererString);
+
+      // then
+      expect(result).toBeFalsy();
+      expect(mocks.configManagerMock.getConfig).toHaveBeenCalledWith('crowi', 'app:siteUrl');
+      expect(mocks.configManagerMock.getConfig).toHaveBeenCalledOnce();
+    });
+
+    it('when the domain of the referer does not match with siteUrl', () => {
+      // setup
+      const siteUrl = 'https://example.com';
+      mocks.configManagerMock.getConfig.mockImplementation(() => {
+        return siteUrl;
+      });
+
+      // when
+      const shareLinkId = '65436ba09ae6983bd608b89c';
+      const refererString = `https://example.org/share/${shareLinkId}`;
+      const result = validateReferer(refererString);
+
+      // then
+      expect(result).toBeFalsy();
+      expect(mocks.configManagerMock.getConfig).toHaveBeenCalledWith('crowi', 'app:siteUrl');
+      expect(mocks.configManagerMock.getConfig).toHaveBeenCalledOnce();
     });
 
   });
 
   it('returns ValidReferer instance', () => {
-    // setup
+    // when
     const shareLinkId = '65436ba09ae6983bd608b89c';
     const refererString = `https://example.com/share/${shareLinkId}`;
-
-    // when
     const result = validateReferer(refererString);
 
     // then

+ 25 - 0
apps/app/src/server/middlewares/certify-shared-file/validate-referer.ts

@@ -1,3 +1,4 @@
+import { configManager } from '~/server/service/config-manager';
 import loggerFactory from '~/utils/logger';
 
 import { ValidReferer } from './interfaces';
@@ -14,6 +15,30 @@ export const validateReferer = (referer: string | undefined): ValidReferer | fal
   }
 
   // siteUrl
+  const siteUrlString = configManager.getConfig('crowi', 'app:siteUrl');
+  if (siteUrlString == null) {
+    logger.warn("Verification referer does not work because 'Site URL' is NOT set. All of attachments in share link page is invisible.");
+    return false;
+  }
+
+  let siteUrl: URL;
+  try {
+    siteUrl = new URL(siteUrlString);
+  }
+  catch (err) {
+    logger.error("The 'app:siteUrl' is invalid");
+    throw err;
+  }
+  let refererUrl: URL;
+  try {
+    refererUrl = new URL(referer);
+  }
+  catch (err) {
+    logger.error("The 'app:siteUrl' is invalid");
+    throw err;
+  }
+
+  // if (refererUrl.hostname !== )
 
   // starts with /share/