diff --git a/backend/canisters/local_user_index/CHANGELOG.md b/backend/canisters/local_user_index/CHANGELOG.md index 58608c038d..8b331350ca 100644 --- a/backend/canisters/local_user_index/CHANGELOG.md +++ b/backend/canisters/local_user_index/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Changed - Change bot cmd number param values from u16 to f64 ([#7095](https://github.com/open-chat-labs/open-chat/pull/7095)) +- Rename access token `parameters` to `command_args` ([#7104](https://github.com/open-chat-labs/open-chat/pull/7104)) ## [[2.0.1530](https://github.com/open-chat-labs/open-chat/releases/tag/v2.0.1530-local_user_index)] - 2024-12-19 diff --git a/backend/canisters/local_user_index/impl/src/queries/access_token.rs b/backend/canisters/local_user_index/impl/src/queries/access_token.rs index 375e22868a..d29beef814 100644 --- a/backend/canisters/local_user_index/impl/src/queries/access_token.rs +++ b/backend/canisters/local_user_index/impl/src/queries/access_token.rs @@ -70,8 +70,7 @@ async fn access_token(args: Args) -> Response { thread_root_message_index: bc.thread_root_message_index, message_id: bc.message_id, command_name: bc.command_name, - parameters: bc.parameters, - version: bc.version, + command_args: bc.command_args, command_text: bc.command_text, bot_api_gateway: state.env.canister_id(), }; diff --git a/backend/canisters/local_user_index/impl/src/updates/execute_bot_command.rs b/backend/canisters/local_user_index/impl/src/updates/execute_bot_command.rs index 72ca07959f..739601b984 100644 --- a/backend/canisters/local_user_index/impl/src/updates/execute_bot_command.rs +++ b/backend/canisters/local_user_index/impl/src/updates/execute_bot_command.rs @@ -31,6 +31,10 @@ fn validate(args: Args, state: &RuntimeState) -> Result>(&args.jwt, state.data.oc_key_pair.public_key_pem()) .map_err(|error| format!("Access token invalid: {error:?}"))?; + if claims.exp() < state.env.now() { + return Err("Access token expired".to_string()); + } + let bot_command_claims = claims.custom(); let calling_user = bot.user_id; let jwt_user = bot_command_claims.bot; diff --git a/backend/canisters/user_index/api/src/main.rs b/backend/canisters/user_index/api/src/main.rs index 2dc4afe948..4aad21f067 100644 --- a/backend/canisters/user_index/api/src/main.rs +++ b/backend/canisters/user_index/api/src/main.rs @@ -64,5 +64,6 @@ fn main() { generate_ts_method!(user_index, submit_proof_of_unique_personhood); generate_ts_method!(user_index, suspend_user); generate_ts_method!(user_index, unsuspend_user); + generate_ts_method!(user_index, update_bot); generate_ts_method!(user_index, update_diamond_membership_subscription); } diff --git a/backend/integration_tests/src/bot_tests.rs b/backend/integration_tests/src/bot_tests.rs index 219cbbf93a..4495b8704b 100644 --- a/backend/integration_tests/src/bot_tests.rs +++ b/backend/integration_tests/src/bot_tests.rs @@ -93,8 +93,7 @@ fn e2e_bot_test() { thread_root_message_index: None, message_id, command_name: command_name.clone(), - parameters: "".to_string(), - version: 1, // TODO: Remove this + command_args: "".to_string(), command_text: command_name.clone(), }), chat, diff --git a/backend/libraries/types/src/access_tokens.rs b/backend/libraries/types/src/access_tokens.rs index ecd73c4189..df153ad078 100644 --- a/backend/libraries/types/src/access_tokens.rs +++ b/backend/libraries/types/src/access_tokens.rs @@ -38,8 +38,7 @@ pub struct BotCommandArgs { pub thread_root_message_index: Option, pub message_id: MessageId, pub command_name: String, - pub parameters: String, - pub version: u32, + pub command_args: String, pub command_text: String, } diff --git a/backend/libraries/types/src/claims.rs b/backend/libraries/types/src/claims.rs index abe5279a77..98050d040e 100644 --- a/backend/libraries/types/src/claims.rs +++ b/backend/libraries/types/src/claims.rs @@ -40,8 +40,7 @@ pub struct BotCommandClaims { pub thread_root_message_index: Option, pub message_id: MessageId, pub command_name: String, - pub parameters: String, - pub version: u32, + pub command_args: String, pub command_text: String, pub bot_api_gateway: CanisterId, } diff --git a/frontend/app/src/components/Input.svelte b/frontend/app/src/components/Input.svelte index dfdcba3ba9..80e7c3546b 100644 --- a/frontend/app/src/components/Input.svelte +++ b/frontend/app/src/components/Input.svelte @@ -15,6 +15,8 @@ children?: Snippet; onblur?: () => void; onfocus?: () => void; + oninput?: () => void; + onenter?: () => void; } @@ -40,6 +42,8 @@ pattern = undefined, onblur = undefined, onfocus = undefined, + oninput = undefined, + onenter = undefined, children, }: InputProps = $props(); @@ -61,6 +65,7 @@ value = parseInt(e.currentTarget.value, 10); } dispatch("change", value); + oninput?.(); }; export function setValue(text: string) { @@ -70,6 +75,7 @@ function keyDown(e: KeyboardEvent) { if (e.key === "Enter") { dispatch("enter"); + onenter?.(); } } diff --git a/frontend/app/src/components/bots/AutoBotBuilder.svelte b/frontend/app/src/components/bots/AutoBotBuilder.svelte index 784cc6c24f..69ab28b304 100644 --- a/frontend/app/src/components/bots/AutoBotBuilder.svelte +++ b/frontend/app/src/components/bots/AutoBotBuilder.svelte @@ -2,13 +2,13 @@ import Reload from "svelte-material-icons/Reload.svelte"; import { validEndpoint, - emptyBotInstance, OpenChat, validateBot, ValidationErrors, type ExternalBot, type SlashCommandSchema, type ValidationErrorMessages, + userStore, } from "openchat-client"; import { i18nKey } from "../../i18n/i18n"; import Input from "../Input.svelte"; @@ -23,19 +23,21 @@ import HoverIcon from "../HoverIcon.svelte"; import { iconSize } from "../../stores/iconSize"; import CommandViewer from "./CommandViewer.svelte"; + import SingleUserSelector from "../home/SingleUserSelector.svelte"; const client = getContext("client"); interface Props { valid: boolean; onUpdate: (bot: ExternalBot) => void; + candidate: ExternalBot; + nameDirty: boolean; } - let { valid = $bindable(), onUpdate }: Props = $props(); + let { valid = $bindable(), onUpdate, candidate, nameDirty }: Props = $props(); let selectedCommand = $state(undefined); let selectedCommandIndex = $state(undefined); let debug = $state(false); - let candidate = $state(emptyBotInstance()); let schemaLoaded = $state(false); let schemaLoading = $state(false); let showNext = $derived( @@ -49,7 +51,7 @@ () => [$state.snapshot(candidate)], async () => { const errors = validateBot(candidate); - if (errors.get("bot_name").length == 0) { + if (errors.get("bot_name").length == 0 && nameDirty) { errors.addErrors("bot_name", await checkUsername(candidate.name)); } return errors; @@ -100,7 +102,7 @@ // let editing = $derived(bot !== undefined); $effect(() => { - const isValid = errors.size === 0; + const isValid = errors.size === 0 && schemaLoaded; if (isValid !== valid) { valid = isValid; } @@ -123,6 +125,15 @@ selectedCommandIndex = index; } + function endpointChanged() { + schemaLoaded = false; + candidate.definition = { + kind: "bot_definition", + description: "", + commands: [], + }; + } + function loadDefinition() { if (!schemaLoading && validEndpoint(candidate.endpoint)) { schemaLoading = true; @@ -173,6 +184,22 @@ bind:value={candidate.id}> + + (candidate.ownerId = ev.detail.userId)} + on:userRemoved={(_) => (candidate.ownerId = "")} + selectedReceiver={$userStore.get(candidate.ownerId)} + placeholder={"bots.builder.ownerLabel"} + autofocus={false} /> +
{#if !errors.has("bot_endpoint")} - - + + {/if}
diff --git a/frontend/app/src/components/bots/BotAvatar.svelte b/frontend/app/src/components/bots/BotAvatar.svelte new file mode 100644 index 0000000000..a00751a01e --- /dev/null +++ b/frontend/app/src/components/bots/BotAvatar.svelte @@ -0,0 +1,12 @@ + + + diff --git a/frontend/app/src/components/bots/BotBuilder.svelte b/frontend/app/src/components/bots/BotBuilder.svelte index c744d62671..a5301da0c8 100644 --- a/frontend/app/src/components/bots/BotBuilder.svelte +++ b/frontend/app/src/components/bots/BotBuilder.svelte @@ -1,5 +1,6 @@
- +
- (bot = b)} bind:valid /> + {#if step === "choose"} + {#if myBots.length === 0} + + + + {:else} +

+ +

+
+ {#each myBots as myBot} + + +
selectBot(myBot)} class="match"> + + + +
+

+ {myBot.name} +

+

+ {myBot.definition.description} +

+
+
+ {/each} +
+ {/if} + {:else if step === "edit" && botState.current !== undefined} + (botState.current = b)} + bind:valid /> + {/if}
+ + diff --git a/frontend/app/src/components/bots/BotExplorer.svelte b/frontend/app/src/components/bots/BotExplorer.svelte index 7cfadf5e69..7f84e72415 100644 --- a/frontend/app/src/components/bots/BotExplorer.svelte +++ b/frontend/app/src/components/bots/BotExplorer.svelte @@ -1,25 +1,19 @@
- + {#if firstError !== undefined && showError}
diff --git a/frontend/app/src/components/bots/botState.ts b/frontend/app/src/components/bots/botState.ts index 7c63c414dd..6b0926b3e8 100644 --- a/frontend/app/src/components/bots/botState.ts +++ b/frontend/app/src/components/bots/botState.ts @@ -79,7 +79,7 @@ export const commands = derived( ...c, kind: b.kind, botName: b.name, - botIcon: b.avatarUrl, + avatarUrl: b.avatarUrl, botId: b.id, botEndpoint: b.endpoint, botDescription: b.definition.description, diff --git a/frontend/app/src/components/home/Home.svelte b/frontend/app/src/components/home/Home.svelte index 785fcf2ecd..6ded09c3f7 100644 --- a/frontend/app/src/components/home/Home.svelte +++ b/frontend/app/src/components/home/Home.svelte @@ -182,6 +182,7 @@ | { kind: "verify_humanity" } | { kind: "select_chat" } | { kind: "register_bot" } + | { kind: "update_bot" } | { kind: "suspended" } | { kind: "no_access" } | { kind: "new_group"; embeddedContent: boolean; candidate: CandidateGroupChat } @@ -270,7 +271,7 @@ } else if (ev instanceof RegisterBot) { modal = { kind: "register_bot" }; } else if (ev instanceof UpdateBot) { - modal = { kind: "register_bot" }; + modal = { kind: "update_bot" }; } else if (ev instanceof SummonWitch) { summonWitch(); } else if (ev instanceof RemoteVideoCallStartedEvent) { @@ -1333,7 +1334,9 @@ {:else if modal.kind === "suspended"} {:else if modal.kind === "register_bot"} - + + {:else if modal.kind === "update_bot"} + {:else if modal.kind === "no_access"} {:else if modal.kind === "not_found"} diff --git a/frontend/app/src/components/home/MakeProposalModal.svelte b/frontend/app/src/components/home/MakeProposalModal.svelte index 64cf2e07db..34dc25f96e 100644 --- a/frontend/app/src/components/home/MakeProposalModal.svelte +++ b/frontend/app/src/components/home/MakeProposalModal.svelte @@ -14,8 +14,10 @@ type Treasury, currentUser as user, cryptoBalance as cryptoBalanceStore, + currentUser, } from "openchat-client"; import { + emptyBotInstance, isPrincipalValid, isSubAccountValid, isUrl, @@ -101,7 +103,7 @@ let refreshingBalance = false; let balanceWithRefresh: BalanceWithRefresh; let achivementName = ""; - let candidateBot: ExternalBot | undefined = undefined; + let candidateBot: ExternalBot = emptyBotInstance($currentUser.userId); let candidateBotValid = false; $: errorMessage = @@ -511,6 +513,8 @@