@@ -28,6 +28,9 @@ import {
2828 getUnpresentedSnapEffects ,
2929 hasPendingSnapAction ,
3030 markSnapEffectsPresented ,
31+ optionalSnapStringArray ,
32+ resolveSnapActionParamsForAction ,
33+ validateSnapActionTargetUrl ,
3134 type SnapRenderState ,
3235} from "../render-state" ;
3336import type { SnapPage , SnapActionHandlers , JsonValue } from "./types" ;
@@ -42,6 +45,15 @@ function optionalString(value: unknown): string | undefined {
4245 return value ? String ( value ) : undefined ;
4346}
4447
48+ function validActionTarget ( value : unknown ) : string | undefined {
49+ const target = String ( value ?? "" ) ;
50+ return validateSnapActionTargetUrl ( target ) ? undefined : target ;
51+ }
52+
53+ function literalStringParam ( value : unknown ) : string {
54+ return typeof value === "string" ? value : "" ;
55+ }
56+
4557function recordValue ( value : unknown ) : Record < string , unknown > | undefined {
4658 return value && typeof value === "object" && ! Array . isArray ( value )
4759 ? ( value as Record < string , unknown > )
@@ -259,25 +271,31 @@ export function SnapViewCoreInner({
259271 ) ;
260272
261273 const handleAction = useCallback ( ( name : unknown , params : unknown ) => {
274+ const p = resolveSnapActionParamsForAction ( name , params , stateRef . current ) ;
262275 const inputs = ( stateRef . current . inputs ?? { } ) as Record < string , JsonValue > ;
263- const p = ( params ?? { } ) as Record < string , unknown > ;
264276 const h = handlersRef . current ;
265277 let result : unknown ;
266278 setActionPending ( name , p ) ;
267279
268280 switch ( name ) {
269281 case "submit" :
270- result = h . submit ( String ( p . target ?? "" ) , inputs ) ;
282+ result = h . submit ( literalStringParam ( p . target ) , inputs ) ;
271283 break ;
272- case "open_url" :
273- result = h . open_url ( String ( p . target ?? "" ) ) ;
284+ case "open_url" : {
285+ const target = validActionTarget ( p . target ) ;
286+ if ( target ) result = h . open_url ( target ) ;
274287 break ;
275- case "open_snap" :
276- result = h . open_snap ( String ( p . target ?? "" ) ) ;
288+ }
289+ case "open_snap" : {
290+ const target = validActionTarget ( p . target ) ;
291+ if ( target ) result = h . open_snap ( target ) ;
277292 break ;
278- case "open_mini_app" :
279- result = h . open_mini_app ( String ( p . target ?? "" ) ) ;
293+ }
294+ case "open_mini_app" : {
295+ const target = validActionTarget ( p . target ) ;
296+ if ( target ) result = h . open_mini_app ( target ) ;
280297 break ;
298+ }
281299 case "view_cast" :
282300 result = h . view_cast ( { hash : String ( p . hash ?? "" ) } ) ;
283301 break ;
@@ -291,7 +309,7 @@ export function SnapViewCoreInner({
291309 result = h . compose_cast ( {
292310 text : p . text ? String ( p . text ) : undefined ,
293311 channelKey : p . channelKey ? String ( p . channelKey ) : undefined ,
294- embeds : Array . isArray ( p . embeds ) ? ( p . embeds as string [ ] ) : undefined ,
312+ embeds : optionalSnapStringArray ( p . embeds ) ,
295313 } ) ;
296314 break ;
297315 case "view_token" :
0 commit comments