Skip to content

Commit 47794f0

Browse files
authored
Merge pull request #19 from opf/impl/69656-remove-allowed-domains-env
Remove 'allowed domains'
2 parents 988fb21 + 147aae0 commit 47794f0

File tree

3 files changed

+5
-74
lines changed

3 files changed

+5
-74
lines changed

README.md

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,7 @@ cd op-blocknote-hocuspocus
1818
npm install
1919

2020
# Start the server with the appropriate environment variables setup
21-
ALLOWED_DOMAINS=your-openproject-domain.com SECRET=secret12345 npm run start
22-
```
23-
24-
For the server to be able to reach to an OpenProject instance, it is necessary to set the environment variable `ALLOWED_DOMAINS`. It is a comma-separated list of domains (and it allows subdomain matching).
25-
26-
```
27-
ALLOWED_DOMAINS=subdomain-openproject.example.com,top-level-openproject.com`
21+
SECRET=secret12345 npm run start
2822
```
2923

3024
The `SECRET` environment variable is a shared value between this application and OpenProject. Make sure to configure the same value in OpenProject - Settings Hocuspocus secret and in the `SECRET` environment variable of this project.
@@ -36,7 +30,6 @@ docker pull openproject/hocuspocus:latest
3630

3731
docker run -d \
3832
-p 1234:1234 \
39-
-e ALLOWED_DOMAINS=your-openproject-domain.com \
4033
-e SECRET=secret12345 \
4134
openproject/hocuspocus:latest
4235
```

src/extensions/openProjectApi.ts

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,27 +30,6 @@ export class OpenProjectApi implements Extension {
3030
}
3131
const decryptedToken = decryptToken(token);
3232

33-
const allowedDomains = process.env.ALLOWED_DOMAINS?.split(',') || [];
34-
if (allowedDomains.length <= 0) {
35-
throw new Error('Unauthorized: No allowed domains configured.');
36-
}
37-
38-
try {
39-
const url = new URL(resourceUrl);
40-
const isAllowed = allowedDomains.some(domain =>
41-
url.hostname === domain.trim() || url.hostname.endsWith('.' + domain.trim())
42-
);
43-
44-
if (!isAllowed) {
45-
throw new Error('Unauthorized: Invalid base URL domain.');
46-
}
47-
} catch (error) {
48-
if (error instanceof TypeError) {
49-
throw new Error('Unauthorized: Invalid base URL format.');
50-
}
51-
throw error;
52-
}
53-
5433
const response = await fetch(resourceUrl, {
5534
method: "GET",
5635
headers: {
@@ -64,7 +43,6 @@ export class OpenProjectApi implements Extension {
6443
}
6544
const jsonData = await response.json() as ApiResponseDocument;
6645

67-
// data.documentName = resourceUrl;
6846
data.context.resourceUrl = resourceUrl;
6947
data.context.token = decryptedToken;
7048
if (!jsonData._links?.update) {

test/extensions/openProjectApi.test.ts

Lines changed: 4 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,14 @@ import { OpenProjectApi, createEditor } from "../../src/extensions/openProjectAp
55

66
describe("OpenProjectApi", () => {
77
let fetchMock: any;
8-
let originalAllowedDomains: string | undefined;
98

109
beforeEach(() => {
1110
fetchMock = vi.fn();
1211
vi.stubGlobal('fetch', fetchMock);
13-
originalAllowedDomains = process.env.ALLOWED_DOMAINS;
14-
process.env.ALLOWED_DOMAINS = 'test.api,example.com';
1512
});
1613

1714
afterEach(() => {
1815
vi.unstubAllGlobals();
19-
process.env.ALLOWED_DOMAINS = originalAllowedDomains;
2016
});
2117

2218
describe("onAuthenticate", () => {
@@ -28,7 +24,7 @@ describe("OpenProjectApi", () => {
2824
).rejects.toThrowError("Unauthorized: Token missing.");
2925
});
3026

31-
test("when the token is invalid", async () => {
27+
test("when the token is invalid throw an error", async () => {
3228
await expect(() =>
3329
new OpenProjectApi().onAuthenticate({
3430
// Invalid token, generated with a different secret
@@ -37,51 +33,15 @@ describe("OpenProjectApi", () => {
3733
).rejects.toThrowError("Unsupported state or unable to authenticate data");
3834
});
3935

40-
test("when ALLOWED_DOMAINS is not configured throw an error", async () => {
41-
delete process.env.ALLOWED_DOMAINS;
42-
43-
await expect(() =>
44-
new OpenProjectApi().onAuthenticate({
45-
token: "7u+b+QRJN7qANls=--URNw83hIWBq3MMIA--jtl+UPdtbniQVFNOs2EcAw==",
46-
} as unknown as onAuthenticatePayload)
47-
).rejects.toThrowError("Unauthorized: No allowed domains configured.");
48-
});
49-
5036
test("when the resourceUrl has invalid format throw an error", async () => {
51-
await expect(() =>
52-
new OpenProjectApi().onAuthenticate({
53-
token: "7u+b+QRJN7qANls=--URNw83hIWBq3MMIA--jtl+UPdtbniQVFNOs2EcAw==",
54-
documentName: "not a valid url",
55-
} as unknown as onAuthenticatePayload)
56-
).rejects.toThrowError("Unauthorized: Invalid base URL format.");
57-
});
37+
fetchMock.mockResolvedValueOnce({ throws: new TypeError("is not a valid URL") });
5838

59-
test("when the resourceUrl domain is not in ALLOWED_DOMAINS throw an error", async () => {
6039
await expect(() =>
6140
new OpenProjectApi().onAuthenticate({
6241
token: "7u+b+QRJN7qANls=--URNw83hIWBq3MMIA--jtl+UPdtbniQVFNOs2EcAw==",
63-
documentName: "https://malicious.com/something/1",
42+
documentName: "not a valid url",
6443
} as unknown as onAuthenticatePayload)
65-
).rejects.toThrowError("Unauthorized: Invalid base URL domain.");
66-
});
67-
68-
test("when the resourceUrl subdomain matches ALLOWED_DOMAINS it should be accepted", async () => {
69-
fetchMock.mockResolvedValueOnce({
70-
ok: true,
71-
status: 200,
72-
json: () => Promise.resolve({}),
73-
});
74-
75-
const data = {
76-
context: {},
77-
connectionConfig: {},
78-
token: "7u+b+QRJN7qANls=--URNw83hIWBq3MMIA--jtl+UPdtbniQVFNOs2EcAw==",
79-
documentName: "https://subdomain.test.api/api/v3/documents/1",
80-
} as unknown as onAuthenticatePayload;
81-
82-
await new OpenProjectApi().onAuthenticate(data);
83-
84-
expect(data.context.resourceUrl).toEqual("https://subdomain.test.api/api/v3/documents/1");
44+
).rejects.toThrowError("Unauthorized: Invalid token or document access denied.");
8545
});
8646

8747
test("when the server does not authorize the request throw an error", async () => {

0 commit comments

Comments
 (0)