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: ensure contentBusId is loaded properly #342

Merged
merged 1 commit into from
Jul 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/PipelineState.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ declare interface PipelineOptions {
ref: string;
partition: string;
path: string;
contentBusId: string;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove it from options, so that it isn't set accidentally

timer: PipelineTimer;
env: object;
}
Expand Down
2 changes: 0 additions & 2 deletions src/PipelineState.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ export class PipelineState {
env: opts.env,
info: getPathInfo(opts.path),
content: new PipelineContent(),
// todo: compute content-bus id from fstab
contentBusId: opts.contentBusId,
owner: opts.owner,
repo: opts.repo,
ref: opts.ref,
Expand Down
5 changes: 2 additions & 3 deletions src/json-pipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,6 @@ async function computeSurrogateKeys(path, contentBusId) {
export async function jsonPipe(state, req) {
const { log } = state;
state.type = 'json';
const { contentBusId } = state;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@stefan-guggisberg this was the cause of the wrong surrogate key

const { extension } = state.info;
const { searchParams } = req.url;
const params = Object.fromEntries(searchParams.entries());
Expand Down Expand Up @@ -174,7 +173,7 @@ export async function jsonPipe(state, req) {
});

// set surrogate keys
const keys = await computeSurrogateKeys(state.info.path, contentBusId);
const keys = await computeSurrogateKeys(state.info.path, state.contentBusId);
res.headers.set('x-surrogate-key', keys.join(' '));

await setCustomResponseHeaders(state, req, res);
Expand All @@ -191,7 +190,7 @@ export async function jsonPipe(state, req) {
await setCustomResponseHeaders(state, req, res);
}
if (res.status === 404) {
const keys = await computeSurrogateKeys(state.info.path, contentBusId);
const keys = await computeSurrogateKeys(state.info.path, state.contentBusId);
res.headers.set('x-surrogate-key', keys.join(' '));
}
return res;
Expand Down
50 changes: 37 additions & 13 deletions src/options-pipe.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/
import { cleanupHeaderValue } from '@adobe/helix-shared-utils';
import { PipelineResponse } from './PipelineResponse.js';
import fetchConfigAll from './steps/fetch-config-all.js';
import setCustomResponseHeaders from './steps/set-custom-response-headers.js';
import fetchConfig from './steps/fetch-config.js';
import { PipelineStatusError } from './PipelineStatusError.js';

/**
* Handles options requests
Expand All @@ -20,18 +23,39 @@ import setCustomResponseHeaders from './steps/set-custom-response-headers.js';
* @returns {Response} a response
*/
export async function optionsPipe(state, request) {
// todo: improve
const response = new PipelineResponse('', {
status: 204,
headers: {
// Set preflight cache duration
'access-control-max-age': '86400',
// Allow content type header
'access-control-allow-headers': 'content-type',
},
});
await fetchConfigAll(state, request, response);
await setCustomResponseHeaders(state, request, response);
try {
await fetchConfig(state, request);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was completely missing! OPTIONS requests would have never worked properly

if (!state.contentBusId) {
return new PipelineResponse('', {
status: 400,
headers: {
'x-error': 'contentBusId missing',
},
});
}

return response;
// todo: improve
const res = new PipelineResponse('', {
status: 204,
headers: {
// Set preflight cache duration
'access-control-max-age': '86400',
// Allow content type header
'access-control-allow-headers': 'content-type',
},
});
await fetchConfigAll(state, request, res);
await setCustomResponseHeaders(state, request, res);

return res;
} catch (e) {
const res = new PipelineResponse('', {
status: e instanceof PipelineStatusError ? e.code : 500,
});
const level = res.status >= 500 ? 'error' : 'info';
state.log[level](`pipeline status: ${res.status} ${e.message}`);
res.headers.set('x-error', cleanupHeaderValue(e.message));
res.headers.set('cache-control', 'no-store, private, must-revalidate');
return res;
}
}
5 changes: 5 additions & 0 deletions test/fixtures/code/helix-config-head-with-script.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,10 @@
"/articles/": "/special/default-article",
"/app": "/spa/index.html"
}
},
"content": {
"/": {
"contentBusId": "foo-id"
}
}
}
5 changes: 5 additions & 0 deletions test/fixtures/code/helix-config-no-head-html.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
{
"head": {
},
"content": {
"/": {
"contentBusId": "foo-id"
}
}
}
5 changes: 5 additions & 0 deletions test/fixtures/code/helix-config-no-head.json
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
{
"content": {
"/": {
"contentBusId": "foo-id"
}
}
}
5 changes: 5 additions & 0 deletions test/fixtures/code/helix-config.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,10 @@
"/articles/": "/special/default-article",
"/app": "/spa/index.html"
}
},
"content": {
"/": {
"contentBusId": "foo-id"
}
}
}
15 changes: 7 additions & 8 deletions test/forms-pipe.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,6 @@ describe('Form POST Requests', () => {
ref: 'ref',
partition: 'live',
path: '/somepath/workbook.json',
contentBusId: 'foobus',
log: console,
s3Loader: mockHelixConfig(new StaticS3Loader()),
});
Expand Down Expand Up @@ -321,15 +320,15 @@ describe('Form POST Requests', () => {
};

it('valid json body', async () => {
const res = await extractBodyData(new PipelineRequest('https://helix-pipeline.com/?contentBusId=foobus', {
const res = await extractBodyData(new PipelineRequest('https://helix-pipeline.com/', {
...defaultRequest,
body: JSON.stringify(validBody),
}), defaultContext);
assert.deepStrictEqual(res, validBody);
});

it('valid urlencoded body', async () => {
const res = await extractBodyData(new PipelineRequest('https://helix-pipeline.com/?contentBusId=foobus', defaultFormUrlEncodedRequest), defaultContext);
const res = await extractBodyData(new PipelineRequest('https://helix-pipeline.com/', defaultFormUrlEncodedRequest), defaultContext);
assert.deepEqual(res, {
data: {
firstname: 'bruce',
Expand All @@ -341,7 +340,7 @@ describe('Form POST Requests', () => {
it('valid urlencoded body, duplicate keys', async () => {
const body = 'foo=bar&foo=zoo&firstname=bruce&lastname=banner';

const res = await extractBodyData(new PipelineRequest('https://helix-pipeline.com/?contentBusId=foobus', {
const res = await extractBodyData(new PipelineRequest('https://helix-pipeline.com/', {
...defaultFormUrlEncodedRequest,
body,
}), defaultContext);
Expand All @@ -356,7 +355,7 @@ describe('Form POST Requests', () => {

it('invalid json body', async () => {
const body = 'foobar';
const res = extractBodyData(new PipelineRequest('https://helix-pipeline.com/?contentBusId=foobus', {
const res = extractBodyData(new PipelineRequest('https://helix-pipeline.com/', {
...defaultRequest,
body,
}), defaultContext);
Expand All @@ -365,7 +364,7 @@ describe('Form POST Requests', () => {

it('empty json body', async () => {
const body = '{}';
const res = extractBodyData(new PipelineRequest('https://helix-pipeline.com/?contentBusId=foobus', {
const res = extractBodyData(new PipelineRequest('https://helix-pipeline.com/', {
...defaultRequest,
body,
}), defaultContext);
Expand All @@ -374,7 +373,7 @@ describe('Form POST Requests', () => {

it('unsupported type', async () => {
const body = '<foo></foo>';
const res = extractBodyData(new PipelineRequest('https://helix-pipeline.com/?contentBusId=foobus', {
const res = extractBodyData(new PipelineRequest('https://helix-pipeline.com/', {
...defaultRequest,
body,
headers: { 'content-type': 'application/xml' },
Expand All @@ -384,7 +383,7 @@ describe('Form POST Requests', () => {

it('invalid urlencoded body, sent json instead', async () => {
const body = '[object Object]';
const res = extractBodyData(new PipelineRequest('https://helix-pipeline.com/?contentBusId=foobus', {
const res = extractBodyData(new PipelineRequest('https://helix-pipeline.com/', {
...defaultFormUrlEncodedRequest,
body,
}), defaultContext);
Expand Down
26 changes: 18 additions & 8 deletions test/html-pipe.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ import assert from 'assert';
import esmock from 'esmock';
import { UnsecuredJWT } from 'jose';
import { FileS3Loader } from './FileS3Loader.js';
import { htmlPipe, PipelineRequest, PipelineState } from '../src/index.js';
import {
htmlPipe, PipelineRequest, PipelineResponse, PipelineState,
} from '../src/index.js';
import { StaticS3Loader } from './StaticS3Loader.js';

describe('HTML Pipe Test', () => {
it('responds with 404 for invalid path', async () => {
Expand All @@ -37,7 +40,6 @@ describe('HTML Pipe Test', () => {
ref: 'super-test',
partition: 'live',
path: '/',
contentBusId: 'foo-id',
}),
new PipelineRequest(new URL('https://www.hlx.live/'), {
headers: {
Expand All @@ -61,7 +63,6 @@ describe('HTML Pipe Test', () => {
ref: 'super-test',
partition: 'live',
path: '/',
contentBusId: 'foo-id',
}),
new PipelineRequest(new URL('https://www.hlx.live/')),
);
Expand All @@ -79,7 +80,7 @@ describe('HTML Pipe Test', () => {
});

const resp = await mockPipe(
new PipelineState({ contentBusId: 'foo', s3Loader: new FileS3Loader() }),
new PipelineState({ s3Loader: new FileS3Loader() }),
new PipelineRequest(new URL('https://www.hlx.live/')),
);
assert.strictEqual(resp.status, 500);
Expand All @@ -105,7 +106,7 @@ describe('HTML Pipe Test', () => {
});

const resp = await htmlPipe(
new PipelineState({ path: '/.auth', contentBusId: 'foo', s3Loader: new FileS3Loader() }),
new PipelineState({ path: '/.auth', s3Loader: new FileS3Loader() }),
req,
);
assert.strictEqual(resp.status, 302);
Expand All @@ -114,7 +115,7 @@ describe('HTML Pipe Test', () => {

it('handles .auth partition', async () => {
const resp = await htmlPipe(
new PipelineState({ partition: '.auth', contentBusId: 'foo', s3Loader: new FileS3Loader() }),
new PipelineState({ partition: '.auth', s3Loader: new FileS3Loader() }),
new PipelineRequest(new URL('https://www.hlx.live/')),
);
assert.strictEqual(resp.status, 401);
Expand All @@ -123,7 +124,17 @@ describe('HTML Pipe Test', () => {

it('responds with 400 for missing contentBusId', async () => {
const resp = await htmlPipe(
new PipelineState({ s3Loader: new FileS3Loader() }),
new PipelineState({
owner: 'owner',
repo: 'repo',
ref: 'ref',
s3Loader: new StaticS3Loader()
.reply(
'helix-code-bus',
'owner/repo/ref/helix-config.json',
new PipelineResponse('{}'),
),
}),
new PipelineRequest(new URL('https://www.hlx.live/')),
);
assert.strictEqual(resp.status, 400);
Expand All @@ -140,7 +151,6 @@ describe('HTML Pipe Test', () => {
ref: 'super-test',
partition: 'live',
path: '/index.md',
contentBusId: 'foo-id',
timer: {
update: () => { },
},
Expand Down
Loading