[WIP] Encryption for secure values (#183)

This commit is contained in:
Gregory Schier
2025-04-15 07:18:26 -07:00
committed by GitHub
parent e114a85c39
commit 2e55a1bd6d
208 changed files with 4063 additions and 28698 deletions

View File

@@ -344,7 +344,7 @@ export type ImportResources = { workspaces: Array<Workspace>, environments: Arra
export type ImportResponse = { resources: ImportResources, };
export type InternalEvent = { id: string, pluginRefId: string, pluginName: string, replyId: string | null, windowContext: WindowContext, payload: InternalEventPayload, };
export type InternalEvent = { id: string, pluginRefId: string, pluginName: string, replyId: string | null, windowContext: PluginWindowContext, payload: InternalEventPayload, };
export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & EmptyPayload | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_summary_request" } & EmptyPayload | { "type": "get_http_authentication_summary_response" } & GetHttpAuthenticationSummaryResponse | { "type": "get_http_authentication_config_request" } & GetHttpAuthenticationConfigRequest | { "type": "get_http_authentication_config_response" } & GetHttpAuthenticationConfigResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "call_http_authentication_action_request" } & CallHttpAuthenticationActionRequest | { "type": "call_http_authentication_action_response" } & EmptyPayload | { "type": "copy_text_request" } & CopyTextRequest | { "type": "copy_text_response" } & EmptyPayload | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "get_key_value_request" } & GetKeyValueRequest | { "type": "get_key_value_response" } & GetKeyValueResponse | { "type": "set_key_value_request" } & SetKeyValueRequest | { "type": "set_key_value_response" } & SetKeyValueResponse | { "type": "delete_key_value_request" } & DeleteKeyValueRequest | { "type": "delete_key_value_response" } & DeleteKeyValueResponse | { "type": "open_window_request" } & OpenWindowRequest | { "type": "window_navigate_event" } & WindowNavigateEvent | { "type": "window_close_event" } | { "type": "close_window_request" } & CloseWindowRequest | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "show_toast_response" } & EmptyPayload | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse;
@@ -356,6 +356,8 @@ export type OpenWindowRequest = { url: string,
*/
label: string, title?: string, size?: WindowSize, dataDirKey?: string, };
export type PluginWindowContext = { "type": "none" } | { "type": "label", label: string, workspace_id: string | null, };
export type PromptTextRequest = { id: string, title: string, label: string, description?: string, defaultValue?: string, placeholder?: string,
/**
* Text to add to the confirmation button
@@ -393,14 +395,17 @@ export type TemplateFunction = { name: string, description?: string,
* Also support alternative names. This is useful for not breaking existing
* tags when changing the `name` property
*/
aliases?: Array<string>, args: Array<FormInput>, };
aliases?: Array<string>, args: Array<TemplateFunctionArg>, };
/**
* Similar to FormInput, but contains
*/
export type TemplateFunctionArg = FormInput;
export type TemplateRenderRequest = { data: JsonValue, purpose: RenderPurpose, };
export type TemplateRenderResponse = { data: JsonValue, };
export type WindowContext = { "type": "none" } | { "type": "label", label: string, };
export type WindowNavigateEvent = { url: string, };
export type WindowSize = { width: number, height: number, };

View File

@@ -24,4 +24,4 @@ export type HttpUrlParameter = { enabled?: boolean, name: string, value: string,
export type WebsocketRequest = { model: "websocket_request", id: string, createdAt: string, updatedAt: string, workspaceId: string, folderId: string | null, authentication: Record<string, any>, authenticationType: string | null, description: string, headers: Array<HttpRequestHeader>, message: string, name: string, sortPriority: number, url: string, urlParameters: Array<HttpUrlParameter>, };
export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, };
export type Workspace = { model: "workspace", id: string, createdAt: string, updatedAt: string, name: string, description: string, encryptionKeyChallenge: string | null, settingValidateCertificates: boolean, settingFollowRedirects: boolean, settingRequestTimeout: number, };

View File

@@ -1,3 +1,3 @@
// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
export type JsonValue = number | string | Array<JsonValue> | { [key in string]?: JsonValue };
export type JsonValue = number | string | boolean | Array<JsonValue> | { [key in string]?: JsonValue } | null;

View File

@@ -1,3 +1,4 @@
import { PluginWindowContext, TemplateFunctionArg } from '@yaakapp-internal/plugins';
import type {
BootRequest,
Context,
@@ -17,7 +18,6 @@ import type {
SendHttpRequestResponse,
TemplateFunction,
TemplateRenderResponse,
WindowContext,
} from '@yaakapp/api';
import console from 'node:console';
import { readFileSync, type Stats, statSync, watch } from 'node:fs';
@@ -45,12 +45,12 @@ export class PluginInstance {
this.#appToPluginEvents = new EventChannel();
// Forward incoming events to onMessage()
this.#appToPluginEvents.listen(async event => {
this.#appToPluginEvents.listen(async (event) => {
await this.#onMessage(event);
})
});
// Reload plugin if the JS or package.json changes
const windowContextNone: WindowContext = { type: 'none' };
const windowContextNone: PluginWindowContext = { type: 'none' };
const fileChangeCallback = async () => {
this.#importModule();
return this.#sendPayload(windowContextNone, { type: 'reload_response' }, null);
@@ -261,10 +261,10 @@ export class PluginInstance {
payload.type === 'call_template_function_request' &&
Array.isArray(this.#mod?.templateFunctions)
) {
const action = this.#mod.templateFunctions.find((a) => a.name === payload.name);
if (typeof action?.onRender === 'function') {
applyFormInputDefaults(action.args, payload.args.values);
const result = await action.onRender(ctx, payload.args);
const fn = this.#mod.templateFunctions.find((a) => a.name === payload.name);
if (typeof fn?.onRender === 'function') {
applyFormInputDefaults(fn.args, payload.args.values);
const result = await fn.onRender(ctx, payload.args);
this.#sendPayload(
windowContext,
{
@@ -317,7 +317,7 @@ export class PluginInstance {
}
#buildEventToSend(
windowContext: WindowContext,
windowContext: PluginWindowContext,
payload: InternalEventPayload,
replyId: string | null = null,
): InternalEvent {
@@ -332,7 +332,7 @@ export class PluginInstance {
}
#sendPayload(
windowContext: WindowContext,
windowContext: PluginWindowContext,
payload: InternalEventPayload,
replyId: string | null,
): string {
@@ -348,12 +348,12 @@ export class PluginInstance {
this.#pluginToAppEvents.emit(event);
}
#sendEmpty(windowContext: WindowContext, replyId: string | null = null): string {
#sendEmpty(windowContext: PluginWindowContext, replyId: string | null = null): string {
return this.#sendPayload(windowContext, { type: 'empty_response' }, replyId);
}
#sendAndWaitForReply<T extends Omit<InternalEventPayload, 'type'>>(
windowContext: WindowContext,
windowContext: PluginWindowContext,
payload: InternalEventPayload,
): Promise<T> {
// 1. Build event to send
@@ -379,7 +379,7 @@ export class PluginInstance {
}
#sendAndListenForEvents(
windowContext: WindowContext,
windowContext: PluginWindowContext,
payload: InternalEventPayload,
onEvent: (event: InternalEventPayload) => void,
): void {
@@ -551,7 +551,7 @@ function genId(len = 5): string {
/** Recursively apply form input defaults to a set of values */
function applyFormInputDefaults(
inputs: FormInput[],
inputs: TemplateFunctionArg[],
values: { [p: string]: JsonPrimitive | undefined },
) {
for (const input of inputs) {
@@ -580,18 +580,3 @@ function watchFile(filepath: string, cb: (filepath: string) => void) {
watchedFiles[filepath] = stat;
});
}
// function prefixStdout(s: string) {
// if (!s.includes('%s')) {
// throw new Error('Console prefix must contain a "%s" replacer');
// }
// interceptStdout((text: string) => {
// const lines = text.split(/\n/);
// let newText = '';
// for (let i = 0; i < lines.length; i++) {
// if (lines[i] == '') continue;
// newText += util.format(s, lines[i]) + '\n';
// }
// return newText.trimEnd();
// });
// }