Copilot commented on code in PR #5751: URL: https://github.com/apache/texera/pull/5751#discussion_r3426022416
########## agent-service/src/auth/jwt.test.ts: ########## @@ -0,0 +1,68 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { describe, expect, test } from "bun:test"; +import { extractUserFromToken, validateToken, createAuthHeaders } from "./jwt"; Review Comment: `extractBearerToken` is used by `server.ts` for auth, but the new JWT unit tests don't cover it. Adding a few cases (valid bearer, wrong scheme, missing token) would protect this parsing logic from regressions. ########## agent-service/src/auth/jwt.test.ts: ########## @@ -0,0 +1,68 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { describe, expect, test } from "bun:test"; +import { extractUserFromToken, validateToken, createAuthHeaders } from "./jwt"; + +function makeToken(payload: Record<string, unknown>): string { + const encode = (o: Record<string, unknown>) => Buffer.from(JSON.stringify(o)).toString("base64"); + return `${encode({ alg: "none", typ: "JWT" })}.${encode(payload)}.signature`; Review Comment: The JWT helper tests currently build tokens with base64 encoding, but the service (e.g., `server.test.ts`) uses base64url for JWT segments. Using base64url here would better match real tokens and would catch decoding issues around `-`/`_` characters and padding. ########## agent-service/src/auth/jwt.test.ts: ########## @@ -0,0 +1,68 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { describe, expect, test } from "bun:test"; +import { extractUserFromToken, validateToken, createAuthHeaders } from "./jwt"; + +function makeToken(payload: Record<string, unknown>): string { + const encode = (o: Record<string, unknown>) => Buffer.from(JSON.stringify(o)).toString("base64"); + return `${encode({ alg: "none", typ: "JWT" })}.${encode(payload)}.signature`; +} + +const nowSeconds = () => Math.floor(Date.now() / 1000); + +describe("extractUserFromToken", () => { + test("maps JWT claims onto a UserInfo", () => { + const token = makeToken({ userId: 7, sub: "alice", email: "[email protected]", role: "ADMIN" }); + expect(extractUserFromToken(token)).toEqual({ uid: 7, name: "alice", email: "[email protected]", role: "ADMIN" }); + }); + + test("defaults missing email and role", () => { + const token = makeToken({ userId: 1, sub: "bob" }); + expect(extractUserFromToken(token)).toEqual({ uid: 1, name: "bob", email: "", role: "REGULAR" }); + }); + + test("throws on a malformed token", () => { + expect(() => extractUserFromToken("not-a-jwt")).toThrow("Failed to decode JWT"); + }); +}); + +describe("validateToken", () => { + test("accepts a token expiring in the future", () => { + expect(validateToken(makeToken({ sub: "a", exp: nowSeconds() + 3600 }))).toBe(true); + }); + + test("rejects an expired token", () => { + expect(validateToken(makeToken({ sub: "a", exp: nowSeconds() - 3600 }))).toBe(false); + }); + + test("treats a token without exp as valid", () => { + expect(validateToken(makeToken({ sub: "a" }))).toBe(true); + }); + + test("rejects a malformed token", () => { + expect(validateToken("garbage")).toBe(false); + }); +}); + +describe("createAuthHeaders", () => { + test("builds bearer auth headers", () => { + expect(createAuthHeaders("tok")).toEqual({ Authorization: "Bearer tok", "Content-Type": "application/json" }); + }); +}); Review Comment: Add basic coverage for `extractBearerToken` (valid bearer, invalid scheme, missing token) so the auth header parsing behavior is pinned down alongside the other JWT helpers. ########## agent-service/src/types/api.ts: ########## @@ -0,0 +1,95 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +// Wire DTOs: request/response bodies exchanged with backend services and the +// WebSocket frames this service sends to its own clients. Distinct from domain +// types (workflow.ts, execution.ts, agent.ts) which model in-memory state. + +import type { WorkflowContent, OperatorPortSchemaMap } from "./workflow"; +import type { ReActStep } from "./agent"; + +// --- Dashboard Service: workflow persistence --- + +export interface Workflow { + wid: number; + name: string; + description?: string; + content: WorkflowContent; + creationTime?: number; + lastModifiedTime?: number; + isPublished?: boolean; +} + +export interface WorkflowPersistRequest { + wid?: number; + name: string; + description?: string; + content: string; + isPublic?: boolean; +} + +// --- Workflow Compiling Service --- + +export interface WorkflowFatalError { + message: string; + details: string; + operatorId: string; + workerId: string; + type: { name: string }; + timestamp: { nanos: number; seconds: number }; +} + +export interface WorkflowCompilationResponse { + physicalPlan?: any; + operatorOutputSchemas: Record<string, OperatorPortSchemaMap>; + operatorErrors: Record<string, WorkflowFatalError>; +} Review Comment: `WorkflowFatalError` here has the *frontend WebSocket* shape (message/details/workerId/type.name/timestamp), but this section is labeled "Workflow Compiling Service" and the existing compile client (`src/api/compile-api.ts`) uses a different/simpler error shape. Keeping two incompatible `WorkflowFatalError` DTOs will be confusing and can lead to incorrect imports later. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
