-
Notifications
You must be signed in to change notification settings - Fork 3
feature | Request Saving format, integrate all tabs and static drafts #40
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
Open
MatiasFarji
wants to merge
10
commits into
caido-community:main
Choose a base branch
from
MatiasFarji:request-saver
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 8 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
4b8c37f
feature | Request Saving format, integrate all tabs and static drafts
MatiasFarji a44f237
Restore session-embed mention and extend it, persist raw via JSON ins…
MatiasFarji 3c23cb2
Restore session-embed mention and extend it, persist raw via JSON ins…
MatiasFarji 8ec1a78
fix | Missmatch notes given stale memory file combined with appending…
MatiasFarji 0d8e8bd
fix | Dangling listener for onSessionCreate on replay associated to h…
MatiasFarji bf8e514
fix | draft raw request decoding to base64 with utf-8 blob associated…
MatiasFarji d4451e9
fix | detection of route reusing hash system, associated to https://g…
MatiasFarji a8a9330
fix | Low warnings and lint errors associated to https://github.com/c…
MatiasFarji 638ac28
fix | Notes legacy repetitive Toast, Note Scema recursive types parsi…
MatiasFarji 1a3dc12
fix | Copy as Markdown button to new version of request mentions
MatiasFarji File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| import type { SDK } from "caido:plugin"; | ||
| import type { ResolvedSavedItem, Result, SavedItem } from "shared"; | ||
| import { error, ok } from "shared"; | ||
|
|
||
| import { getSavedItemSchema } from "../schemas/savedItem"; | ||
|
|
||
| const REQUEST_RAW_QUERY = ` | ||
| query GetRequestRaw($id: ID!) { | ||
| request(id: $id) { | ||
| raw | ||
| } | ||
| } | ||
| `; | ||
|
|
||
| const RESPONSE_RAW_QUERY = ` | ||
| query GetResponseRaw($id: ID!) { | ||
| response(id: $id) { | ||
| raw | ||
| } | ||
| } | ||
| `; | ||
|
|
||
| /** | ||
| * Resolves a saved item (read from the note's own JSON content) back to | ||
| * its live raw HTTP content. For "history"/"replay" items, only the ID | ||
| * is stored, so this always fetches fresh from Caido; `found: false` is | ||
| * returned if the original request/response no longer exists. | ||
| */ | ||
| export async function getSavedItem( | ||
| sdk: SDK, | ||
| item: SavedItem, | ||
| ): Promise<Result<ResolvedSavedItem>> { | ||
| try { | ||
| getSavedItemSchema.parse({ item }); | ||
|
|
||
| if (item.kind === "request") { | ||
| if (item.sourceKind === "draft") { | ||
| // Never sent, so there's no Request.id to fetch — the raw text | ||
| // and connection info were stored directly in the note. | ||
| if ( | ||
| item.draftRaw === undefined || | ||
| item.draftHost === undefined || | ||
| item.draftPort === undefined || | ||
| item.draftIsTls === undefined | ||
| ) { | ||
| sdk.console.error("Saved draft is missing required draft fields"); | ||
| return ok({ found: false }); | ||
| } | ||
|
|
||
| return ok({ | ||
| found: true, | ||
| kind: "request", | ||
| sourceKind: "draft", | ||
| raw: item.draftRaw, | ||
| draftConnection: { | ||
| host: item.draftHost, | ||
| port: item.draftPort, | ||
| isTls: item.draftIsTls, | ||
| }, | ||
| replaySessionId: item.replaySessionId, | ||
| sessionLabel: item.sessionLabel, | ||
| label: item.label, | ||
| }); | ||
| } | ||
|
|
||
| const response = await sdk.graphql.execute<{ | ||
| request: { raw: string } | undefined; | ||
| }>(REQUEST_RAW_QUERY, { id: item.refId }); | ||
|
|
||
| if (response.errors?.length) { | ||
| sdk.console.error( | ||
| `GraphQL error fetching request ${item.refId}: ${response.errors.map((e) => e.message).join(", ")}`, | ||
| ); | ||
| } | ||
|
|
||
| if (!response.data?.request) { | ||
| return ok({ found: false }); | ||
| } | ||
|
|
||
| return ok({ | ||
| found: true, | ||
| kind: "request", | ||
| sourceKind: item.sourceKind, | ||
| raw: response.data.request.raw, | ||
| requestId: item.refId, | ||
| replaySessionId: item.replaySessionId, | ||
| sessionLabel: item.sessionLabel, | ||
| label: item.label, | ||
| }); | ||
| } | ||
|
|
||
| if (!item.parentRequestId) { | ||
| // Defensive: a response saved before this field existed, or saved | ||
| // through some path that didn't capture it. Without the parent | ||
| // request ID we can't support replay for this item. | ||
| sdk.console.error("Saved response is missing its parent request ID"); | ||
| } | ||
|
|
||
| const response = await sdk.graphql.execute<{ | ||
| response: { raw: string } | undefined; | ||
| }>(RESPONSE_RAW_QUERY, { id: item.refId }); | ||
|
|
||
| if (response.errors?.length) { | ||
| sdk.console.error( | ||
| `GraphQL error fetching response ${item.refId}: ${response.errors.map((e) => e.message).join(", ")}`, | ||
| ); | ||
| } | ||
|
|
||
| if (!response.data?.response) { | ||
| return ok({ found: false }); | ||
| } | ||
|
|
||
| return ok({ | ||
| found: true, | ||
| kind: "response", | ||
| sourceKind: item.sourceKind, | ||
| raw: response.data.response.raw, | ||
| ...(item.parentRequestId ? { requestId: item.parentRequestId } : {}), | ||
| label: item.label, | ||
| }); | ||
| } catch (err) { | ||
| sdk.console.error(`Error resolving saved item: ${err}`); | ||
| return error(err instanceof Error ? err.message : String(err)); | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| import { z } from "zod"; | ||
|
|
||
| /** | ||
| * The kind of context a saved request/response was captured from. | ||
| * - "history": Search, HTTP History, or Sitemap - all share the same | ||
| * underlying Request/Response rows, so the saved ID is the canonical one. | ||
| * - "replay": captured from a Replay pane after the request was actually | ||
| * sent (it has a real, persisted ID by that point). | ||
| * - "draft": captured from a Replay pane *before* it was ever sent. There | ||
| * is no Request.id to point to yet, so the raw content itself is stored | ||
| * directly instead of a reference. | ||
| */ | ||
| export const savedItemSourceKindSchema = z.enum(["history", "replay", "draft"]); | ||
|
|
||
| /** | ||
| * Validates a `SavedItem` as it comes back out of a note's own JSON | ||
| * content — the note file is user-editable on disk, so these attrs are | ||
| * untrusted input. | ||
| */ | ||
| export const savedItemSchema = z.object({ | ||
| kind: z.enum(["request", "response"]), | ||
| refId: z.string(), | ||
| parentRequestId: z.string().optional(), | ||
| sourceKind: savedItemSourceKindSchema, | ||
| replaySessionId: z.string().optional(), | ||
| sessionLabel: z.string().optional(), | ||
| draftRaw: z.string().optional(), | ||
| draftHost: z.string().optional(), | ||
| draftPort: z.number().int().min(1).max(65535).optional(), | ||
| draftIsTls: z.boolean().optional(), | ||
| label: z.string().optional(), | ||
| }); | ||
|
|
||
| export const getSavedItemSchema = z.object({ | ||
| item: savedItemSchema, | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.