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

Introduce new response headers for world readable/writable realm #999

Merged
Merged
Show file tree
Hide file tree
Changes from 6 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
16 changes: 9 additions & 7 deletions packages/host/tests/helpers/index.gts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import ms from 'ms';
import {
Kind,
RealmAdapter,
RealmPermissions,
FileRef,
LooseSingleCardDocument,
baseRealm,
Expand Down Expand Up @@ -523,6 +524,7 @@ async function setupTestRealm({
});
}

let permissions: RealmPermissions['users'] = { '*': ['read', 'write'] };
realm = new Realm({
url: realmURL,
adapter,
Expand All @@ -535,11 +537,11 @@ async function setupTestRealm({
getIndexHTML: async () =>
`<html><body>Intentionally empty index.html (these tests will not exercise this capability)</body></html>`,
matrix: testMatrix,
permissions: { '*': ['read', 'write'] },
permissions,
realmSecretSeed: "shhh! it's a secret",
});
loader.prependURLHandlers([
(req) => sourceFetchRedirectHandle(req, adapter, realmURL!),
(req) => sourceFetchRedirectHandle(req, adapter, realm),
(req) => sourceFetchReturnUrlHandle(req, realm.maybeHandle.bind(realm)),
]);

Expand Down Expand Up @@ -805,13 +807,13 @@ export class TestRealmAdapter implements RealmAdapter {
}

createStreamingResponse(
unresolvedRealmURL: string,
realm: Realm,
_request: Request,
responseInit: ResponseInit,
cleanup: () => void,
) {
let s = new WebMessageStream();
let response = createResponse(unresolvedRealmURL, s.readable, responseInit);
let response = createResponse(realm, s.readable, responseInit);
messageCloseHandler(s.readable, cleanup);
return { response, writable: s.writable };
}
Expand Down Expand Up @@ -887,14 +889,14 @@ export async function sourceFetchReturnUrlHandle(
export async function sourceFetchRedirectHandle(
request: Request,
adapter: RealmAdapter,
realmURL: string,
realm: Realm,
) {
let urlParts = new URL(request.url).pathname.split('.');
if (
isCardSourceFetch(request) &&
urlParts.length === 1 //has no extension
) {
const realmPaths = new RealmPaths(realmURL);
const realmPaths = new RealmPaths(realm.url);
const localPath = realmPaths.local(request.url);
const ref = await getFileWithFallbacks(
localPath,
Expand All @@ -912,7 +914,7 @@ export async function sourceFetchRedirectHandle(
ref.content instanceof Uint8Array ||
typeof ref.content === 'string')
) {
let r = createResponse(realmURL, ref.content, {
let r = createResponse(realm, ref.content, {
headers: {
'last-modified': formatRFC7231(ref.lastModified),
},
Expand Down
6 changes: 3 additions & 3 deletions packages/realm-server/node-realm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
} from 'fs-extra';
import { join } from 'path';
import { Duplex } from 'node:stream';
import type { UpdateEventData } from '@cardstack/runtime-common/realm';
import type { Realm, UpdateEventData } from '@cardstack/runtime-common/realm';
import jwt from 'jsonwebtoken';

export class NodeAdapter implements RealmAdapter {
Expand Down Expand Up @@ -132,14 +132,14 @@ export class NodeAdapter implements RealmAdapter {
}

createStreamingResponse(
unresolvedRealmURL: string,
realm: Realm,
request: Request,
responseInit: ResponseInit,
cleanup: () => void,
) {
let s = new MessageStream();
let response = createResponse(
unresolvedRealmURL,
realm,
null,
responseInit,
) as ResponseWithNodeStream;
Expand Down
94 changes: 93 additions & 1 deletion packages/realm-server/tests/realm-server-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,11 @@ module('Realm Server', function (hooks) {
testRealmURL.href,
'realm url header is correct',
);
assert.strictEqual(
response.get('X-boxel-realm-public-readable'),
'true',
'realm is public readable',
);
assert.deepEqual(json, {
data: {
id: `${testRealmHref}person-1`,
Expand Down Expand Up @@ -197,7 +202,7 @@ module('Realm Server', function (hooks) {
});

test('serves a card POST request', async function (assert) {
assert.expect(8);
assert.expect(9);
let id: string | undefined;
let response = await expectEvent({
assert,
Expand Down Expand Up @@ -246,6 +251,11 @@ module('Realm Server', function (hooks) {
testRealmURL.href,
'realm url header is correct',
);
assert.strictEqual(
response.get('X-boxel-realm-public-readable'),
'true',
'realm is public readable',
);
let json = response.body;

if (isSingleCardDocument(json)) {
Expand Down Expand Up @@ -322,6 +332,11 @@ module('Realm Server', function (hooks) {
testRealmURL.href,
'realm url header is correct',
);
assert.strictEqual(
response.get('X-boxel-realm-public-readable'),
'true',
'realm is public readable',
);

let json = response.body;
assert.ok(json.data.meta.lastModified, 'lastModified exists');
Expand Down Expand Up @@ -404,6 +419,12 @@ module('Realm Server', function (hooks) {
testRealmURL.href,
'realm url header is correct',
);
assert.strictEqual(
response.get('X-boxel-realm-public-readable'),
'true',
'realm is public readable',
);

let cardFile = join(dir.name, entry);
assert.strictEqual(existsSync(cardFile), false, 'card json does not exist');
});
Expand Down Expand Up @@ -433,6 +454,11 @@ module('Realm Server', function (hooks) {
testRealmURL.href,
'realm url header is correct',
);
assert.strictEqual(
response.get('X-boxel-realm-public-readable'),
'true',
'realm is public readable',
);
let cardFile = join(dir.name, entry);
assert.strictEqual(existsSync(cardFile), false, 'card json does not exist');
});
Expand All @@ -448,6 +474,12 @@ module('Realm Server', function (hooks) {
testRealmURL.href,
'realm url header is correct',
);
assert.strictEqual(
response.get('X-boxel-realm-public-readable'),
'true',
'realm is public readable',
);

let result = response.body.toString().trim();
assert.strictEqual(result, cardSrc, 'the card source is correct');
assert.ok(response.headers['last-modified'], 'last-modified header exists');
Expand All @@ -464,6 +496,11 @@ module('Realm Server', function (hooks) {
testRealmURL.href,
'realm url header is correct',
);
assert.strictEqual(
response.get('X-boxel-realm-public-readable'),
'true',
'realm is public readable',
);
assert.strictEqual(response.headers['location'], '/person.gts');
});

Expand All @@ -478,6 +515,11 @@ module('Realm Server', function (hooks) {
testRealmURL.href,
'realm url header is correct',
);
assert.strictEqual(
response.get('X-boxel-realm-public-readable'),
'true',
'realm is public readable',
);
assert.strictEqual(response.headers['location'], '/person-1.json');
});

Expand All @@ -492,6 +534,11 @@ module('Realm Server', function (hooks) {
testRealmURL.href,
'realm url header is correct',
);
assert.strictEqual(
response.get('X-boxel-realm-public-readable'),
'true',
'realm is public readable',
);
assert.strictEqual(response.headers['location'], '/person');
});

Expand Down Expand Up @@ -519,6 +566,11 @@ module('Realm Server', function (hooks) {
testRealmURL.href,
'realm url header is correct',
);
assert.strictEqual(
response.get('X-boxel-realm-public-readable'),
'true',
'realm is public readable',
);
let cardFile = join(dir.name, entry);
assert.strictEqual(
existsSync(cardFile),
Expand Down Expand Up @@ -551,6 +603,11 @@ module('Realm Server', function (hooks) {
testRealmURL.href,
'realm url header is correct',
);
assert.strictEqual(
response.get('X-boxel-realm-public-readable'),
'true',
'realm is public readable',
);
let cardFile = join(dir.name, entry);
assert.strictEqual(
existsSync(cardFile),
Expand Down Expand Up @@ -585,6 +642,11 @@ module('Realm Server', function (hooks) {
testRealmURL.href,
'realm url header is correct',
);
assert.strictEqual(
response.get('X-boxel-realm-public-readable'),
'true',
'realm is public readable',
);

let srcFile = join(dir.name, entry);
assert.ok(existsSync(srcFile), 'card src exists');
Expand Down Expand Up @@ -749,6 +811,11 @@ module('Realm Server', function (hooks) {
testRealmURL.href,
'realm url header is correct',
);
assert.strictEqual(
response.get('X-boxel-realm-public-readable'),
'true',
'realm is public readable',
);

let json = response.body;
assert.deepEqual(json.data.attributes, {
Expand Down Expand Up @@ -818,6 +885,11 @@ module('Realm Server', function (hooks) {
testRealmURL.href,
'realm URL header is correct',
);
assert.strictEqual(
response.get('X-boxel-realm-public-readable'),
'true',
'realm is public readable',
);
let body = response.text.trim();
let moduleAbsolutePath = resolve(join(__dirname, '..', 'person.gts'));

Expand All @@ -844,6 +916,11 @@ module('Realm Server', function (hooks) {
testRealmURL.href,
'realm url header is correct',
);
assert.strictEqual(
response.get('X-boxel-realm-public-readable'),
'true',
'realm is public readable',
);
let json = response.body;
assert.deepEqual(
json,
Expand Down Expand Up @@ -906,6 +983,11 @@ module('Realm Server', function (hooks) {
testRealmURL.href,
'realm url header is correct',
);
assert.strictEqual(
response.get('X-boxel-realm-public-readable'),
'true',
'realm is public readable',
);
let json = response.body;
assert.strictEqual(
json.data.length,
Expand All @@ -930,6 +1012,11 @@ module('Realm Server', function (hooks) {
testRealmURL.href,
'realm url header is correct',
);
assert.strictEqual(
response.get('X-boxel-realm-public-readable'),
'true',
'realm is public readable',
);
let json = response.body;
assert.deepEqual(
json,
Expand Down Expand Up @@ -1067,6 +1154,11 @@ module('Realm Server', function (hooks) {
testRealmURL.href,
'realm url header is correct',
);
assert.strictEqual(
response.get('X-boxel-realm-public-readable'),
'true',
'realm is public readable',
);
assert.deepEqual(json, {
data: {
id: `${testRealmHref}new-card`,
Expand Down
7 changes: 5 additions & 2 deletions packages/runtime-common/create-response.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { Realm } from './realm';

export function createResponse(
unresolvedRealmURL: string,
realm: Realm,
body?: BodyInit | null | undefined,
init?: ResponseInit | undefined,
relaxDocumentDomain?: boolean, // only use for CI!
Expand All @@ -8,7 +10,8 @@ export function createResponse(
...init,
headers: {
...init?.headers,
'X-Boxel-Realm-Url': unresolvedRealmURL,
'X-Boxel-Realm-Url': realm.url,
...(realm.isPublicReadable && { 'X-Boxel-Realm-Public-Readable': 'true' }),
vary: 'Accept',
'Access-Control-Expose-Headers': 'X-Boxel-Realm-Url,Authorization',
...(relaxDocumentDomain
Expand Down
Loading
Loading