diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index e55ae53ac8..1bd52cea0e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -77,6 +77,10 @@ jobs: if: always() run: pnpm run lint working-directory: packages/realm-server + - name: Lint Runtime Common + if: always() + run: pnpm run lint + working-directory: packages/runtime-common ai-bot-test: name: AI bot Tests diff --git a/packages/runtime-common/create-response.ts b/packages/runtime-common/create-response.ts index d42cb69c5e..1fac00e691 100644 --- a/packages/runtime-common/create-response.ts +++ b/packages/runtime-common/create-response.ts @@ -11,9 +11,12 @@ export function createResponse( headers: { ...init?.headers, 'X-Boxel-Realm-Url': realm.url, - ...(realm.isPublicReadable && { 'X-Boxel-Realm-Public-Readable': 'true' }), + ...(realm.isPublicReadable && { + 'X-Boxel-Realm-Public-Readable': 'true', + }), vary: 'Accept', - 'Access-Control-Expose-Headers': 'X-Boxel-Realm-Url,X-Boxel-Realm-Public-Readable,Authorization', + 'Access-Control-Expose-Headers': + 'X-Boxel-Realm-Url,X-Boxel-Realm-Public-Readable,Authorization', ...(relaxDocumentDomain ? { // we use this header to permit cross origin communication to diff --git a/packages/runtime-common/error.ts b/packages/runtime-common/error.ts index b49365f769..637280ed22 100644 --- a/packages/runtime-common/error.ts +++ b/packages/runtime-common/error.ts @@ -139,10 +139,7 @@ export function serializableError(err: any): any { return result; } -export function responseWithError( - realm: Realm, - error: CardError, -): Response { +export function responseWithError(realm: Realm, error: CardError): Response { return createResponse( realm, JSON.stringify({ errors: [serializableError(error)] }), @@ -154,10 +151,7 @@ export function responseWithError( ); } -export function methodNotAllowed( - realm: Realm, - request: Request, -): Response { +export function methodNotAllowed(realm: Realm, request: Request): Response { return responseWithError( realm, new CardError(`${request.method} not allowed for ${request.url}`, { @@ -171,30 +165,15 @@ export function notFound( request: Request, message = `Could not find ${request.url}`, ): Response { - return responseWithError( - realm, - new CardError(message, { status: 404 }), - ); + return responseWithError(realm, new CardError(message, { status: 404 })); } -export function badRequest( - realm: Realm, - message: string, -): Response { - return responseWithError( - realm, - new CardError(message, { status: 400 }), - ); +export function badRequest(realm: Realm, message: string): Response { + return responseWithError(realm, new CardError(message, { status: 400 })); } -export function systemUnavailable( - realm: Realm, - message: string, -): Response { - return responseWithError( - realm, - new CardError(message, { status: 503 }), - ); +export function systemUnavailable(realm: Realm, message: string): Response { + return responseWithError(realm, new CardError(message, { status: 503 })); } export function systemError( diff --git a/packages/runtime-common/etc/test-fixtures.ts b/packages/runtime-common/etc/test-fixtures.ts index b6d549f246..a2140617bb 100644 --- a/packages/runtime-common/etc/test-fixtures.ts +++ b/packages/runtime-common/etc/test-fixtures.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-useless-escape */ export const cardSrc = ` import { contains, diff --git a/packages/runtime-common/helpers/ai.ts b/packages/runtime-common/helpers/ai.ts index 7cf030fb40..5d97665077 100644 --- a/packages/runtime-common/helpers/ai.ts +++ b/packages/runtime-common/helpers/ai.ts @@ -155,7 +155,7 @@ function generatePatchCallSpecification( properties: {}, }; - const { id: removedIdField, ...fields } = cardApi.getFields(def, { + const { id: _removedIdField, ...fields } = cardApi.getFields(def, { usedFieldsOnly: false, }); diff --git a/packages/runtime-common/matrix-client.ts b/packages/runtime-common/matrix-client.ts index bd470e0715..dd83966f80 100644 --- a/packages/runtime-common/matrix-client.ts +++ b/packages/runtime-common/matrix-client.ts @@ -148,7 +148,9 @@ export class MatrixClient { return json as T; } - async getProfile(userId: string): Promise<{ displayname: string } | undefined> { + async getProfile( + userId: string, + ): Promise<{ displayname: string } | undefined> { let response = await this.request( `_matrix/client/v3/profile/${userId}`, 'GET', diff --git a/packages/runtime-common/package.json b/packages/runtime-common/package.json index 93a7dc93d0..3ff4e96fda 100644 --- a/packages/runtime-common/package.json +++ b/packages/runtime-common/package.json @@ -63,5 +63,9 @@ "peerDependencies": { "@babel/core": "^7.24.3", "ember-cli-htmlbars": "^6.3.0" + }, + "scripts": { + "lint": "eslint . --cache --ext ts", + "lint:js:fix": "eslint . --fix" } } diff --git a/packages/runtime-common/realm-permission-checker.ts b/packages/runtime-common/realm-permission-checker.ts index 9bbd8deaf9..720d3ac826 100644 --- a/packages/runtime-common/realm-permission-checker.ts +++ b/packages/runtime-common/realm-permission-checker.ts @@ -13,17 +13,21 @@ export default class RealmPermissionChecker { async for(username: string) { let doesMatrixUserProfileExist = false; if (this.realmPermissions['users']) { - doesMatrixUserProfileExist = !!(await this.matrixClient.getProfile(username)); + doesMatrixUserProfileExist = !!(await this.matrixClient.getProfile( + username, + )); } return Array.from( new Set([ - ...(doesMatrixUserProfileExist ? this.realmPermissions['users'] || [] : []), + ...(doesMatrixUserProfileExist + ? this.realmPermissions['users'] || [] + : []), ...(this.realmPermissions['*'] || []), ...(this.realmPermissions[username] || []), - ])); + ]), + ); } - async can(username: string, action: 'read' | 'write') { let userPermissions = await this.for(username); return userPermissions.includes(action); diff --git a/packages/runtime-common/realm.ts b/packages/runtime-common/realm.ts index d85f3f33d4..0a66d33044 100644 --- a/packages/runtime-common/realm.ts +++ b/packages/runtime-common/realm.ts @@ -747,7 +747,10 @@ export class Realm { hash.update(this.#realmSecretSeed); let hashedResponse = uint8ArrayToHex(await hash.digest()); if (hashedResponse === challenge) { - let permissions = await (new RealmPermissionChecker(this.#permissions, this.#matrixClient)).for(user); + let permissions = await new RealmPermissionChecker( + this.#permissions, + this.#matrixClient, + ).for(user); let jwt = this.#adapter.createJWT( { user, @@ -968,30 +971,24 @@ export class Realm { request: Request, neededPermission: 'read' | 'write', ) { - let endpontsWithoutAuthNeeded: RouteTable = new Map([ - // authentication endpoint - [ - SupportedMimeType.Session, - new Map([ - ['POST' as Method, new Map([['/_session', true]])], - ]), - ], - // SSE endpoint - [ - SupportedMimeType.EventStream, - new Map([ - ['GET' as Method, new Map([['/_message', true]])], - ]), - ], - // serve a text/html endpoint - [ - SupportedMimeType.HTML, - new Map([ - ['GET' as Method, new Map([['/.*', true]])], - ]), - ], - ]); - + let endpontsWithoutAuthNeeded: RouteTable = new Map([ + // authentication endpoint + [ + SupportedMimeType.Session, + new Map([['POST' as Method, new Map([['/_session', true]])]]), + ], + // SSE endpoint + [ + SupportedMimeType.EventStream, + new Map([['GET' as Method, new Map([['/_message', true]])]]), + ], + // serve a text/html endpoint + [ + SupportedMimeType.HTML, + new Map([['GET' as Method, new Map([['/.*', true]])]]), + ], + ]); + if ( lookupRouteTable(endpontsWithoutAuthNeeded, this.paths, request) || request.method === 'HEAD' || @@ -1016,11 +1013,14 @@ export class Realm { token = this.#adapter.verifyJWT(tokenString, this.#realmSecretSeed); let realmPermissionChecker = new RealmPermissionChecker( this.#permissions, - this.#matrixClient + this.#matrixClient, ); - + let permissions = await realmPermissionChecker.for(token.user); - if (JSON.stringify(token.permissions.sort()) !== JSON.stringify(permissions.sort())) { + if ( + JSON.stringify(token.permissions.sort()) !== + JSON.stringify(permissions.sort()) + ) { throw new AuthenticationError( 'User permissions have been updated. Please refresh the token', ); diff --git a/packages/runtime-common/router.ts b/packages/runtime-common/router.ts index 76218f3ef3..13a9feee14 100644 --- a/packages/runtime-common/router.ts +++ b/packages/runtime-common/router.ts @@ -43,10 +43,14 @@ export function extractSupportedMimeType( export type RouteTable = Map>>; -export function lookupRouteTable(routeTable: RouteTable, paths: RealmPaths, request: Request) { +export function lookupRouteTable( + routeTable: RouteTable, + paths: RealmPaths, + request: Request, +) { let acceptMimeType = extractSupportedMimeType( request.headers.get('Accept') as unknown as null | string | [string], - ) + ); if (!acceptMimeType) { return; } @@ -77,7 +81,10 @@ export function lookupRouteTable(routeTable: RouteTable, paths: RealmPaths } export class Router { - #routeTable: RouteTable = new Map>>(); + #routeTable: RouteTable = new Map< + SupportedMimeType, + Map> + >(); log = logger('realm:router'); #paths: RealmPaths; constructor(mountURL: URL) {