View Issue Details

This issue affects 1 person(s).
 0
IDProjectCategoryView StatusLast Update
20792Bug reportsTheme editorpublic2026-10-22 16:16
Reportervirgilev Assigned To 
PrioritynoneSeverityminor 
Status newResolutionopen 
Product Version7.7.x 
Summary20792: New survey editor silently drops theme options not defined by fruity_twentythree
Description

The new survey editor validates theme settings against a fixed schema that only lists the option names of fruity_twentythree (themeSettingUpdateJoi). A custom survey theme extending fruity_twentythree can declare extra options in its config.xml, including in optionsOrderReact. The editor shows these options but cannot save them: validation rejects the unknown keys before the request is sent.

The server side already handles this correctly, since it only keeps the options declared in the theme manifest. The client-side whitelist is therefore not needed for safety. It only blocks custom themes.

Steps To Reproduce

In Configuration > Themes, import custom_options_demo.zip. This is a minimal theme that extends fruity_twentythree and declares one extra option, headerBackgroundColor (colorpicker), listed in optionsOrderReact.
Import the survey limesurvey_survey_custom_theme_options.lss, which uses this theme.
Open the survey in the new editor, then go to Presentation > Theme options. The "Header background color" option is shown under Appearance.
Change the color, for example to #2a2f38.
Reload the page.
Expected: The new value is saved and still shown after the reload.

Actual:

The editor shows "Saved at …", but the value goes back to #ffffff after the reload.
The browser console shows ValidationError: "props.headerBackgroundColor" is not allowed.
The PATCH to /rest/v1/survey-detail/{sid} only contains {"entity":"themeSettings","props":{"templateName":"custom_options_demo"}}, so the option is dropped without telling the user.

TagsNo tags attached.
Attached Files
limesurvey_survey_custom_theme_options.lss (17,895 bytes)   
<?xml version="1.0" encoding="UTF-8"?>
<document>
 <LimeSurveyDocType>Survey</LimeSurveyDocType>
 <DBVersion>648</DBVersion>
 <languages>
  <language>en</language>
 </languages>
 <groups>
  <fields>
   <fieldname>gid</fieldname>
   <fieldname>sid</fieldname>
   <fieldname>group_order</fieldname>
   <fieldname>randomization_group</fieldname>
   <fieldname>grelevance</fieldname>
  </fields>
  <rows>
   <row>
    <gid>35</gid>
    <sid>426842</sid>
    <group_order>1</group_order>
    <randomization_group />
    <grelevance>1</grelevance>
   </row>
  </rows>
 </groups>
 <group_l10ns>
  <fields>
   <fieldname>id</fieldname>
   <fieldname>gid</fieldname>
   <fieldname>group_name</fieldname>
   <fieldname>description</fieldname>
   <fieldname>language</fieldname>
   <fieldname>sid</fieldname>
   <fieldname>group_order</fieldname>
   <fieldname>randomization_group</fieldname>
   <fieldname>grelevance</fieldname>
  </fields>
  <rows>
   <row>
    <id>68</id>
    <gid>35</gid>
    <group_name>My first question group</group_name>
    <description />
    <language>en</language>
    <sid>426842</sid>
    <group_order>1</group_order>
    <randomization_group />
    <grelevance>1</grelevance>
   </row>
  </rows>
 </group_l10ns>
 <questions>
  <fields>
   <fieldname>qid</fieldname>
   <fieldname>parent_qid</fieldname>
   <fieldname>sid</fieldname>
   <fieldname>gid</fieldname>
   <fieldname>type</fieldname>
   <fieldname>title</fieldname>
   <fieldname>preg</fieldname>
   <fieldname>other</fieldname>
   <fieldname>mandatory</fieldname>
   <fieldname>encrypted</fieldname>
   <fieldname>question_order</fieldname>
   <fieldname>scale_id</fieldname>
   <fieldname>same_default</fieldname>
   <fieldname>relevance</fieldname>
   <fieldname>question_theme_name</fieldname>
   <fieldname>modulename</fieldname>
   <fieldname>same_script</fieldname>
  </fields>
  <rows>
   <row>
    <qid>469</qid>
    <parent_qid>0</parent_qid>
    <sid>426842</sid>
    <gid>35</gid>
    <type>T</type>
    <title>G01Q05</title>
    <preg />
    <other>N</other>
    <mandatory>N</mandatory>
    <encrypted>N</encrypted>
    <question_order>4</question_order>
    <scale_id>0</scale_id>
    <same_default>0</same_default>
    <relevance>1</relevance>
    <question_theme_name>longfreetext</question_theme_name>
    <modulename />
    <same_script>0</same_script>
   </row>
  </rows>
 </questions>
 <question_l10ns>
  <fields>
   <fieldname>id</fieldname>
   <fieldname>qid</fieldname>
   <fieldname>question</fieldname>
   <fieldname>help</fieldname>
   <fieldname>script</fieldname>
   <fieldname>language</fieldname>
  </fields>
  <rows>
   <row>
    <id>931</id>
    <qid>469</qid>
    <question>Any comment?</question>
    <help />
    <script />
    <language>en</language>
   </row>
  </rows>
 </question_l10ns>
 <question_attributes>
  <fields>
   <fieldname>qid</fieldname>
   <fieldname>attribute</fieldname>
   <fieldname>value</fieldname>
   <fieldname>language</fieldname>
  </fields>
  <rows>
   <row>
    <qid>469</qid>
    <attribute>cssclass</attribute>
    <value />
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>display_rows</attribute>
    <value />
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>em_validation_q</attribute>
    <value />
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>em_validation_q_tip</attribute>
    <value />
    <language>en</language>
   </row>
   <row>
    <qid>469</qid>
    <attribute>hidden</attribute>
    <value>0</value>
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>hide_tip</attribute>
    <value>0</value>
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>image</attribute>
    <value />
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>input_size</attribute>
    <value />
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>maximum_chars</attribute>
    <value />
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>page_break</attribute>
    <value>0</value>
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>random_group</attribute>
    <value />
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>save_as_default</attribute>
    <value>N</value>
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>statistics_graphtype</attribute>
    <value>0</value>
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>statistics_showgraph</attribute>
    <value>1</value>
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>text_input_width</attribute>
    <value />
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>time_limit</attribute>
    <value />
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>time_limit_action</attribute>
    <value>1</value>
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>time_limit_countdown_message</attribute>
    <value />
    <language>en</language>
   </row>
   <row>
    <qid>469</qid>
    <attribute>time_limit_disable_next</attribute>
    <value>0</value>
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>time_limit_disable_prev</attribute>
    <value>0</value>
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>time_limit_message</attribute>
    <value />
    <language>en</language>
   </row>
   <row>
    <qid>469</qid>
    <attribute>time_limit_message_delay</attribute>
    <value />
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>time_limit_message_style</attribute>
    <value />
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>time_limit_timer_style</attribute>
    <value />
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>time_limit_warning</attribute>
    <value />
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>time_limit_warning_2</attribute>
    <value />
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>time_limit_warning_2_display_time</attribute>
    <value />
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>time_limit_warning_2_message</attribute>
    <value />
    <language>en</language>
   </row>
   <row>
    <qid>469</qid>
    <attribute>time_limit_warning_2_style</attribute>
    <value />
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>time_limit_warning_display_time</attribute>
    <value />
    <language />
   </row>
   <row>
    <qid>469</qid>
    <attribute>time_limit_warning_message</attribute>
    <value />
    <language>en</language>
   </row>
   <row>
    <qid>469</qid>
    <attribute>time_limit_warning_style</attribute>
    <value />
    <language />
   </row>
  </rows>
 </question_attributes>
 <surveys>
  <fields>
   <fieldname>sid</fieldname>
   <fieldname>gsid</fieldname>
   <fieldname>admin</fieldname>
   <fieldname>expires</fieldname>
   <fieldname>startdate</fieldname>
   <fieldname>adminemail</fieldname>
   <fieldname>anonymized</fieldname>
   <fieldname>format</fieldname>
   <fieldname>savetimings</fieldname>
   <fieldname>template</fieldname>
   <fieldname>language</fieldname>
   <fieldname>additional_languages</fieldname>
   <fieldname>datestamp</fieldname>
   <fieldname>usecookie</fieldname>
   <fieldname>allowregister</fieldname>
   <fieldname>allowsave</fieldname>
   <fieldname>autonumber_start</fieldname>
   <fieldname>autoredirect</fieldname>
   <fieldname>allowprev</fieldname>
   <fieldname>printanswers</fieldname>
   <fieldname>ipaddr</fieldname>
   <fieldname>ipanonymize</fieldname>
   <fieldname>refurl</fieldname>
   <fieldname>showsurveypolicynotice</fieldname>
   <fieldname>publicstatistics</fieldname>
   <fieldname>publicgraphs</fieldname>
   <fieldname>listpublic</fieldname>
   <fieldname>htmlemail</fieldname>
   <fieldname>sendconfirmation</fieldname>
   <fieldname>tokenanswerspersistence</fieldname>
   <fieldname>assessments</fieldname>
   <fieldname>usecaptcha</fieldname>
   <fieldname>usetokens</fieldname>
   <fieldname>bounce_email</fieldname>
   <fieldname>attributedescriptions</fieldname>
   <fieldname>emailresponseto</fieldname>
   <fieldname>emailnotificationto</fieldname>
   <fieldname>tokenlength</fieldname>
   <fieldname>showxquestions</fieldname>
   <fieldname>showgroupinfo</fieldname>
   <fieldname>shownoanswer</fieldname>
   <fieldname>showqnumcode</fieldname>
   <fieldname>bouncetime</fieldname>
   <fieldname>bounceprocessing</fieldname>
   <fieldname>bounceaccounttype</fieldname>
   <fieldname>bounceaccounthost</fieldname>
   <fieldname>bounceaccountpass</fieldname>
   <fieldname>bounceaccountencryption</fieldname>
   <fieldname>bounceaccountuser</fieldname>
   <fieldname>showwelcome</fieldname>
   <fieldname>showprogress</fieldname>
   <fieldname>questionindex</fieldname>
   <fieldname>navigationdelay</fieldname>
   <fieldname>alloweditaftercompletion</fieldname>
   <fieldname>googleanalyticsstyle</fieldname>
   <fieldname>googleanalyticsapikey</fieldname>
   <fieldname>tokenencryptionoptions</fieldname>
   <fieldname>access_mode</fieldname>
   <fieldname>lastmodified</fieldname>
  </fields>
  <rows>
   <row>
    <sid>426842</sid>
    <gsid>1</gsid>
    <admin>inherit</admin>
    <adminemail>inherit</adminemail>
    <anonymized>I</anonymized>
    <format>I</format>
    <savetimings>I</savetimings>
    <template>custom_options_demo</template>
    <language>en</language>
    <additional_languages />
    <datestamp>I</datestamp>
    <usecookie>I</usecookie>
    <allowregister>I</allowregister>
    <allowsave>I</allowsave>
    <autonumber_start>0</autonumber_start>
    <autoredirect>I</autoredirect>
    <allowprev>I</allowprev>
    <printanswers>I</printanswers>
    <ipaddr>I</ipaddr>
    <ipanonymize>I</ipanonymize>
    <refurl>I</refurl>
    <showsurveypolicynotice>0</showsurveypolicynotice>
    <publicstatistics>I</publicstatistics>
    <publicgraphs>I</publicgraphs>
    <listpublic>I</listpublic>
    <htmlemail>I</htmlemail>
    <sendconfirmation>I</sendconfirmation>
    <tokenanswerspersistence>I</tokenanswerspersistence>
    <assessments>I</assessments>
    <usecaptcha>E</usecaptcha>
    <usetokens>N</usetokens>
    <bounce_email>inherit</bounce_email>
    <emailresponseto>inherit</emailresponseto>
    <emailnotificationto>inherit</emailnotificationto>
    <tokenlength>-1</tokenlength>
    <showxquestions>N</showxquestions>
    <showgroupinfo>I</showgroupinfo>
    <shownoanswer>I</shownoanswer>
    <showqnumcode>N</showqnumcode>
    <bounceprocessing>N</bounceprocessing>
    <showwelcome>I</showwelcome>
    <showprogress>I</showprogress>
    <questionindex>-1</questionindex>
    <navigationdelay>-1</navigationdelay>
    <alloweditaftercompletion>I</alloweditaftercompletion>
    <tokenencryptionoptions />
    <access_mode>O</access_mode>
    <lastmodified>2026-10-22 00:00:00</lastmodified>
   </row>
  </rows>
 </surveys>
 <surveys_languagesettings>
  <fields>
   <fieldname>surveyls_survey_id</fieldname>
   <fieldname>surveyls_policy_error</fieldname>
   <fieldname>surveyls_email_invite_subj</fieldname>
   <fieldname>surveyls_email_invite</fieldname>
   <fieldname>surveyls_email_remind_subj</fieldname>
   <fieldname>surveyls_email_remind</fieldname>
   <fieldname>surveyls_email_register_subj</fieldname>
   <fieldname>surveyls_email_register</fieldname>
   <fieldname>surveyls_email_confirm_subj</fieldname>
   <fieldname>surveyls_email_confirm</fieldname>
   <fieldname>surveyls_dateformat</fieldname>
   <fieldname>surveyls_attributecaptions</fieldname>
   <fieldname>surveyls_alias</fieldname>
   <fieldname>email_admin_notification_subj</fieldname>
   <fieldname>email_admin_notification</fieldname>
   <fieldname>email_admin_responses_subj</fieldname>
   <fieldname>email_admin_responses</fieldname>
   <fieldname>surveyls_numberformat</fieldname>
   <fieldname>attachments</fieldname>
   <fieldname>surveyls_language</fieldname>
   <fieldname>surveyls_title</fieldname>
   <fieldname>surveyls_description</fieldname>
   <fieldname>surveyls_welcometext</fieldname>
   <fieldname>surveyls_endtext</fieldname>
   <fieldname>surveyls_policy_notice</fieldname>
   <fieldname>surveyls_policy_notice_label</fieldname>
   <fieldname>surveyls_url</fieldname>
   <fieldname>surveyls_urldescription</fieldname>
  </fields>
  <rows>
   <row>
    <surveyls_survey_id>426842</surveyls_survey_id>
    <surveyls_policy_error />
    <surveyls_email_invite_subj>Invitation to participate in a survey</surveyls_email_invite_subj>
    <surveyls_email_invite>Dear {FIRSTNAME},&lt;br /&gt;
&lt;br /&gt;
You have been invited to participate in a survey.&lt;br /&gt;
&lt;br /&gt;
The survey is titled:&lt;br /&gt;
"{SURVEYNAME}"&lt;br /&gt;
&lt;br /&gt;
"{SURVEYDESCRIPTION}"&lt;br /&gt;
&lt;br /&gt;
To participate, please click on the link below.&lt;br /&gt;
&lt;br /&gt;
Sincerely,&lt;br /&gt;
&lt;br /&gt;
{ADMINNAME} ({ADMINEMAIL})&lt;br /&gt;
&lt;br /&gt;
----------------------------------------------&lt;br /&gt;
Click here to do the survey:&lt;br /&gt;
{SURVEYURL}&lt;br /&gt;
&lt;br /&gt;
If you do not want to participate in this survey and don't want to receive any more invitations please click the following link:&lt;br /&gt;
{OPTOUTURL}&lt;br /&gt;
&lt;br /&gt;
If you are blocklisted but want to participate in this survey and want to receive invitations please click the following link:&lt;br /&gt;
{OPTINURL}</surveyls_email_invite>
    <surveyls_email_remind_subj>Reminder to participate in a survey</surveyls_email_remind_subj>
    <surveyls_email_remind>Dear {FIRSTNAME},&lt;br /&gt;
&lt;br /&gt;
Recently we invited you to participate in a survey.&lt;br /&gt;
&lt;br /&gt;
We note that you have not yet completed the survey, and wish to remind you that the survey is still available should you wish to take part.&lt;br /&gt;
&lt;br /&gt;
The survey is titled:&lt;br /&gt;
"{SURVEYNAME}"&lt;br /&gt;
&lt;br /&gt;
"{SURVEYDESCRIPTION}"&lt;br /&gt;
&lt;br /&gt;
To participate, please click on the link below.&lt;br /&gt;
&lt;br /&gt;
Sincerely,&lt;br /&gt;
&lt;br /&gt;
{ADMINNAME} ({ADMINEMAIL})&lt;br /&gt;
&lt;br /&gt;
----------------------------------------------&lt;br /&gt;
Click here to do the survey:&lt;br /&gt;
{SURVEYURL}&lt;br /&gt;
&lt;br /&gt;
If you do not want to participate in this survey and don't want to receive any more invitations please click the following link:&lt;br /&gt;
{OPTOUTURL}</surveyls_email_remind>
    <surveyls_email_register_subj>Survey registration confirmation</surveyls_email_register_subj>
    <surveyls_email_register>Dear {FIRSTNAME},&lt;br /&gt;
&lt;br /&gt;
You, or someone using your email address, have registered to participate in an online survey titled {SURVEYNAME}.&lt;br /&gt;
&lt;br /&gt;
To complete this survey, click on the following URL:&lt;br /&gt;
&lt;br /&gt;
{SURVEYURL}&lt;br /&gt;
&lt;br /&gt;
If you have any questions about this survey, or if you did not register to participate and believe this email is in error, please contact {ADMINNAME} at {ADMINEMAIL}.</surveyls_email_register>
    <surveyls_email_confirm_subj>Confirmation of your participation in our survey</surveyls_email_confirm_subj>
    <surveyls_email_confirm>Dear {FIRSTNAME},&lt;br /&gt;
&lt;br /&gt;
This email is to confirm that you have completed the survey titled {SURVEYNAME} and your response has been saved. Thank you for participating.&lt;br /&gt;
&lt;br /&gt;
If you have any further questions about this email, please contact {ADMINNAME} on {ADMINEMAIL}.&lt;br /&gt;
&lt;br /&gt;
Sincerely,&lt;br /&gt;
&lt;br /&gt;
{ADMINNAME}</surveyls_email_confirm>
    <surveyls_dateformat>9</surveyls_dateformat>
    <surveyls_alias />
    <email_admin_notification_subj>Response submission for survey {SURVEYNAME}</email_admin_notification_subj>
    <email_admin_notification>Hello,&lt;br /&gt;
&lt;br /&gt;
A new response was submitted for your survey '{SURVEYNAME}'.&lt;br /&gt;
&lt;br /&gt;
Click the following link to see the individual response:&lt;br /&gt;
{VIEWRESPONSEURL}&lt;br /&gt;
&lt;br /&gt;
Click the following link to edit the individual response:&lt;br /&gt;
{EDITRESPONSEURL}&lt;br /&gt;
&lt;br /&gt;
View statistics by clicking here:&lt;br /&gt;
{STATISTICSURL}</email_admin_notification>
    <email_admin_responses_subj>Response submission for survey {SURVEYNAME} with results</email_admin_responses_subj>
    <email_admin_responses>Hello,&lt;br /&gt;
&lt;br /&gt;
A new response was submitted for your survey '{SURVEYNAME}'.&lt;br /&gt;
&lt;br /&gt;
Click the following link to see the individual response:&lt;br /&gt;
{VIEWRESPONSEURL}&lt;br /&gt;
&lt;br /&gt;
Click the following link to edit the individual response:&lt;br /&gt;
{EDITRESPONSEURL}&lt;br /&gt;
&lt;br /&gt;
View statistics by clicking here:&lt;br /&gt;
{STATISTICSURL}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The following answers were given by the participant:&lt;br /&gt;
{ANSWERTABLE}</email_admin_responses>
    <surveyls_numberformat>0</surveyls_numberformat>
    <surveyls_language>en</surveyls_language>
    <surveyls_title>Custom theme options</surveyls_title>
    <surveyls_description />
    <surveyls_welcometext />
    <surveyls_endtext />
    <surveyls_policy_notice />
    <surveyls_policy_notice_label />
    <surveyls_url />
    <surveyls_urldescription />
   </row>
  </rows>
 </surveys_languagesettings>
 <surveys_groups>
  <fields>
   <fieldname>gsid</fieldname>
   <fieldname>name</fieldname>
   <fieldname>title</fieldname>
   <fieldname>template</fieldname>
   <fieldname>description</fieldname>
   <fieldname>parent_id</fieldname>
   <fieldname>alwaysavailable</fieldname>
  </fields>
  <rows>
   <row>
    <gsid>1</gsid>
    <name>default</name>
    <title>Default</title>
    <description>Default survey group</description>
   </row>
  </rows>
 </surveys_groups>
</document>
Bug heat0
Complete LimeSurvey version number (& build)7.5.1+261007 (also present in 7.7.0 and the current development branch)
I will donate to the project if issue is resolvedNo
Browser
Database type & version PostgreSQL 18.6
Server OS (if known)
Webserver software & version (if known)
PHP Version8.4.27
Git branch / Pull Request URL

Users monitoring this issue

There are no users monitoring this issue.

Activities

Issue History

Date Modified Username Field Change
2026-10-22 16:16 virgilev New Issue
2026-10-22 16:16 virgilev File Added: limesurvey_survey_custom_theme_options.lss
2026-10-22 16:16 virgilev File Added: custom_options_demo.zip