From 604ec1d9b0a286bc5ceda12cf6370b3f46cfa7f7 Mon Sep 17 00:00:00 2001 From: Paul Lizer Date: Mon, 26 Jan 2026 15:43:59 -0500 Subject: [PATCH 1/4] release note updating for github coplilot --- .../update_release_notes.instructions.md | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 .github/instructions/update_release_notes.instructions.md diff --git a/.github/instructions/update_release_notes.instructions.md b/.github/instructions/update_release_notes.instructions.md new file mode 100644 index 00000000..353cea48 --- /dev/null +++ b/.github/instructions/update_release_notes.instructions.md @@ -0,0 +1,90 @@ +--- +applyTo: '**' +--- + +# Release Notes Update Instructions + +## When to Update Release Notes + +After completing a code change (bug fix, new feature, enhancement, or breaking change), always ask the user: + +**"Would you like me to update the release notes in `docs/explanation/release_notes.md`?"** + +## If the User Confirms Yes + +Update the release notes file following these guidelines: + +### 1. Location +Release notes are located at: `docs/explanation/release_notes.md` + +### 2. Version Placement +- Add new entries under the **current version** from `config.py` +- If the version has changed, create a new version section at the TOP of the file +- Format: `### **(vX.XXX.XXX)**` + +### 3. Entry Categories + +Organize entries under the appropriate category: + +#### New Features +```markdown +#### New Features + +* **Feature Name** + * Brief description of what the feature does and its benefits. + * Additional details about functionality or configuration. + * (Ref: relevant files, components, or concepts) +``` + +#### Bug Fixes +```markdown +#### Bug Fixes + +* **Fix Name** + * Description of what was broken and how it was fixed. + * Impact or affected areas. + * (Ref: relevant files, functions, or components) +``` + +#### User Interface Enhancements +```markdown +#### User Interface Enhancements + +* **Enhancement Name** + * Description of UI/UX improvements. + * (Ref: relevant templates, CSS, or JavaScript files) +``` + +#### Breaking Changes +```markdown +#### Breaking Changes + +* **Change Name** + * Description of what changed and why. + * **Migration**: Steps users need to take (if any). +``` + +### 4. Entry Format Guidelines + +- **Bold the title** of each entry +- Use bullet points for details +- Include a `(Ref: ...)` line with relevant file names, functions, or concepts +- Keep descriptions concise but informative +- Focus on user-facing impact, not implementation details + +### 5. Example Entry + +```markdown +* **Custom Logo Display Fix** + * Fixed issue where custom logos uploaded via Admin Settings would only display on the admin page but not on other pages (chat, sidebar, landing page). + * Root cause was overly aggressive sanitization removing logo URLs from public settings. + * (Ref: logo display, settings sanitization, template conditionals) +``` + +### 6. Checklist Before Updating + +- [ ] Confirm the current version in `config.py` +- [ ] Determine the correct category (New Feature, Bug Fix, Enhancement, Breaking Change) +- [ ] Write a clear, user-focused description +- [ ] Include relevant file/component references +- [ ] Place entry under the correct version section From 2cf955b304ef713bbef50bb8243b8bc61cf00d1e Mon Sep 17 00:00:00 2001 From: Paul Lizer Date: Mon, 26 Jan 2026 15:44:51 -0500 Subject: [PATCH 2/4] fixed logo bug issue --- application/single_app/functions_settings.py | 9 + .../single_app/static/images/custom_logo.png | Bin 11705 -> 11877 bytes .../static/images/custom_logo_dark.png | Bin 13770 -> 13468 bytes .../single_app/static/images/favicon.ico | Bin 2237 -> 2237 bytes .../CUSTOM_LOGO_NOT_DISPLAYING_FIX.md | 102 +++++++++++ docs/explanation/release_notes.md | 12 ++ .../test_custom_logo_sanitization_fix.py | 172 ++++++++++++++++++ 7 files changed, 295 insertions(+) create mode 100644 docs/explanation/fixes/v0.237.002/CUSTOM_LOGO_NOT_DISPLAYING_FIX.md create mode 100644 functional_tests/test_custom_logo_sanitization_fix.py diff --git a/application/single_app/functions_settings.py b/application/single_app/functions_settings.py index 7a411064..5fa59f12 100644 --- a/application/single_app/functions_settings.py +++ b/application/single_app/functions_settings.py @@ -794,6 +794,15 @@ def sanitize_settings_for_user(full_settings: dict) -> dict: else: sanitized[k] = v + # Add boolean flags for logo/favicon existence so templates can check without exposing base64 data + # These fields are stripped by the base64 filter above, but templates need to know if logos exist + if 'custom_logo_base64' in full_settings: + sanitized['custom_logo_base64'] = bool(full_settings.get('custom_logo_base64')) + if 'custom_logo_dark_base64' in full_settings: + sanitized['custom_logo_dark_base64'] = bool(full_settings.get('custom_logo_dark_base64')) + if 'custom_favicon_base64' in full_settings: + sanitized['custom_favicon_base64'] = bool(full_settings.get('custom_favicon_base64')) + return sanitized def sanitize_settings_for_logging(full_settings: dict) -> dict: diff --git a/application/single_app/static/images/custom_logo.png b/application/single_app/static/images/custom_logo.png index 45a99fd35f8834db8920ea29bd2bfee10fe754d2..ecf6e6521a737af56bcc82321caff1acefb63494 100644 GIT binary patch literal 11877 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 F{sTGwC=37q literal 11705 zcmbVSRa6~Iv>XoZ2Pe23+%-UOcXyW%G`Ks#NpK79?(P!Yf`s56+}-VQKi=p2d27w= z{@T5I?Vg^ls$CJvic+XZ1V{h?pvp*#tG>xcAr>>W>TnOaU_DBI+I)C%)bp z)DoVjSDG5`{x84BCr;~*>b_9INPx|uba42cuEGbiKVs_SN6>^?j;s7*^5Ty()1Si6 zmsAq{v1{tYzgx`qFKQ!1j-o=65^h`CMS^@d4aZIAmc5?i%Al=0>q<()^-kaY3%
txT=*o8&jKB+g$Gzp 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 Kc$KK}xBmg`z(eK$ diff --git a/application/single_app/static/images/custom_logo_dark.png b/application/single_app/static/images/custom_logo_dark.png index b3beb694201dc8b371e45c973895a95e211eab8e..4f28194576a32f4463ff13ac96521f979e739bb0 100644 GIT binary patch literal 13468 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 aj13{1xX1-4^7hveoPvysbhV^u=>Gr|kZNTB literal 13770 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 diff --git a/application/single_app/static/images/favicon.ico b/application/single_app/static/images/favicon.ico index d8f058f6866570b29f44c682b05a6a010bdedf60..3dc7742a5aa3422badbf8b10bf9d9a21db43f205 100644 GIT binary patch delta 2147 zcmV-p2%Pu55xo&M000310{{>Z00000AON%h001@s000;m00000AOP9|008O%001B$ z00000AOQIT006`U005K01QU@-5r2D0L_t(|oZXT=YgADXhMzg--n+TG!4Q;X!S$m^ zAdLutz!rjqm5qfz#M0iTa6}pyLj(TN8CT)v@OVyWBq9HCt}BrZ@b9zDDp|&mx43YKp8AzT{ysO6$xEn z?7vxfomD64T`^tE>rook&uomI^l}9mtq%>Xu zPW05gyWeK-9q-IN4Hvf1>2$gys>h1$wyJQ)q8-#*5Tuv#w8kNI{+FyVvk_Fa6|>M5 z)pq4R9g(tb;P@A&`1Qw?=6thgE|OneI?H7rsn+V==WEx@`=9&>>ixw;Z?Zl+xyMNDb1=my90x&(kH{Ld2Xs8Cj_vH0_%@Arf zPk*sl@{dpbPcF+g+bsF5ll(H!<>`5wrrV#1FTU?wksJZA(+Iv1!|&C|5CSHV;UmDU zvc?R!$Q!}x1{*L_mgTJP^J@hhrpR1qhQFygqM$>b4;u|z#8wy4!2Nb{y3B0>?0;!c zrvZCbMf#L-)DknI+(~ejMpvrn9g-`dI-$S>pchDf85O@;#cnmc4At#ww1LPqF3rDf z{$IasLNi=5q6bKGNfFM0vX9h9svIQnyH%V75JR)t51=8$rvUy6&2Uh_A1ruGj5Yxs z1+k8Tt1zrsuMd+@XLEl_fUiX21b@MXfkKrv5J92+6188+{K?gLHz)g_-#+zDet~E9B-Pc$^`d4~G_C2hLcjM(IzL}tPin~mfPo}Wc8HVNFc<#qwrt0AY-|kM zwq06M-irzN0L#*PdQf3z)r4CTamWhWt@lT?IAf?Mtk{iWQsoC z5h^7Vl?h1&LE=+kghHtl^iUB-Vh=$?1sPF65cCw$gG4V8g;`MKKo3PoFM{SnFM=ZK z%sAuBJ@=dy`_7qr@7$b8rH3Bw2b;V1zH6_aZ~Yu#fB^;=pbM(jLg#CNyMIz0?msqs zO-Qi>%Q~kzu7~PPeNNFLZ1vxB2;l)V8bb@b>B0xu>s8Kpl?$vg8Vz&c_kEC~eFiSa z*5&pN_4*C0VoqdhUn-J$vYhco&Qjx)cQf+_uX5Tczp2rQjPHv6RV$gtPy=(3MTDL^ ztr(0B?KY}+iPk#iI3Dy)o{|1v-1z@_F;%y=tb}C;H?0^|fQWI+^;9v=C zOmeI<#h0y1&6j+TpN%k1IaZTG4drXCi>*(g@RXDjE|YC!_AbgMA@H%*biNC~c-IR} zpKsG2naJcf5xLC;{@AIEa^NT8y$^n~5ArhCQgbSgap0Zpd-eCQ%73I+IV2)$eUSa} z-lgtAuX2t9KOJ>D<#&AW_p?fiL;8VzvE8lP4vF?_0IqANqsDi5m6KlOuv31|t9-|S zcSHrVj{5spr5X2GmaX6{&3*7&yvkXx{_aj%RmOafSH1F|PWgaWneu^u@PQAr%J)e5 z^*Pyuvvdb%>9|vQJby3Tc>tGSHVuQb*cr106!V%`Y4xZ-X1nEDjjA?cMG=tfgX)c5 z)8|0cFr!}qTAq|R5i<K5U_U(HG^|sgbR}e0}T9&+d^=x^>WKU`SO*`YJoEqHHrzMW0ps$V?4Ou(Vw} zfuBT{tw0UKJ?)mwu@v_qgjJpXJASrdHrtL=3HRb^CSl6TZ^af~M5cFk%sF?(-vWvU zAHpUd!sht6Vtzus8g}f2#1XSJ$;L#qVz52>-c+|G#7on}Az>!-D!}-$a#4-bo z8!3oZ+U)-|5Y~gNo@Lp}obsQ@k};fX4;nYm=t2hm1zc?!ISV@@8Tr)A=gho5&-3HV zd`m9*8E*2hb8ez6OKD2;0+&3JPvw79?|WJO|ADSTcCM0(s&+ax((~J^cTwsG7+?TY Z_!}p`4s?)md<*~p002ovPDHLkV1oEUB}o7P delta 2140 zcmV-i2&4DC5xo&J000310{{>Z00000AONfZ001@s000;m00000AOPP20080v001B$ z00000AOQRW006;}Gbev@NklmfY+^R8-~&_4nfII--Z}7J zAV2|V8)u=d{@CTyL<&Tk$3kxHSphiUQdQNuD_i00AU3zTy;y(NKGoHIGv1K%yFU|@ z-RfxsJ&AZu&~=r)z=z4xPsI0wcpoC0N#wOf+}2=hO0AyWHnaJ*6m>l!?4A$v)Ji!zgS)^x4;%0` zu%qyyX_|9a2UmZ_!$&tB7R^C^Qmt0&wwK31`faQo`IXC+GKupe=lM(Ez>dtj^zFjs z{ZH5L>R(&v^?Lmo%`L+}cN$&uO?ITJ1_Q~2A{r)At0CfeI^VEa#Qvj3S0WW{1NklE|Ni8Oau}^y_q+^_kO>7&uKAl-vA9=Va|0bb0zmr0?*)I{8PH|{cg|EtjC#Tmb80+H zaGqitP3>or8(}tMzzkrQNbXLCZ=B&R6W)f|K@;mBaf{E(_q%_#A4=@TyQ20kDK`!A zJg9Gz_J~R;Y*dqt8d)yCHeR4|5wz`+hYtxJ1#yGModoWK9F-ug-a_x% z%*TiJkL~~Mh)-2BosDD*04FW^FB)e*W+}Zvro~=jyU6ojtGb#7;FH?4(AEJI3SKhk zome$rg&@ZoueTku*Qj)5Oid{->sH^Hb@BL;n z>oqj8)NwA`<|5{5sq2zus;cUj$Avuu`QO<7>8JSA1jO>_uY4c!gzY*1Vg3T2y9jiB zlr?CR-T@zz*8~xN!%0LzRCt{2l})HsRTRhn>+H4G*=yh1RUi48A!bJCqlBU|A*mop z92G_=luAK^iZBuz1Q8WvL2TcS;^!e21d-vS4SA%!o zyVvVSDh(RkA8gKE`>eCq$6jk6V91amLwZnmTu#0o!qx775&mPt*F}jrm^UjmaU;x@ z4md>vGWz7fb%`-PfL3edGT-#zs5{v7IGc`%=>eE6l_>9X)Pn;CfQz$rsd+%NIbTdY zsBXZ8M^Rj$D@oQ!DqTw1CL*J3dMuc{X=Y0$$z1@rJBkZ3)WQgQ#J)8H05maQOslQ~ z0AOe|7G4y8yt^|IkPED+x%vj@unfRtyTsc>v>=#%MeyD3bdK6sK@od0u%@W6$_-z3 z&bMFUs6RVloGL6QgE{hRowJ=!VPGoqnUHiNxxb6tCPewOGg)l~Fy8aR%IDd1Oj7BR z^fy(#EkyY^m>!TQPe>}ABd_DAFH58JVEULu*&?ZbbT+<6OwY0DUR7PmQFloyJ(S@= zHa#g(o@UdrVDb(}zF$l`63Y+#i%ntGCMW30%kGnx$!<2C;3z+Elzn3QJxY0fMz@eu zZkAMkjtA4nt2&$la31cHa0Ca+ZUGs9!m~F42!K{6bXwio009IPJ7IPcTlpM_TJH2K zKnshE!vti2_6qU#n)3dK3j6l=ohv`u_2cauxtf^T!=`Hs;Io2qcF++<@j~VGGekH> zL}%UoZvdHyCfxlffVv39RHw>E0n`qR13t=ss1Fb@;*K5lRC_;1Ipc*NEI?bmz=s{= z7rD--k1pBp%h$Kw{Oor9q*n*67Dmi$$v|b7-6*ZwJ^~uG?OI&DaN>Lw*L;DXt__fBXyPgxt5!-6qC0^Wb_I;VL%?VH*54#{{jL4j&Uu2 z$G8qa(ajWD@1`u!z(N28$GE;sJ;Uxa=!thnzf1s}jqfdr{4fP9#|WC0 zS5HYP+iI`3O*^NrNUd)G$e?^DfJgg`_V1T_;gJKq^SK-Z0D;0>I8J4!!}A<8?qncZ z?9=ZXAgl&?Go`e+qUtB|;xtZT9Mh>^&;M%RDx4rmaSPyFO-y|*BCD&aIwT^uR9YRE zwk!xCoXI(BTiaujWl1$r{m~cs|Cej2_L)kqFeHPZL&-}j2CA2MXf4F3QpzYcVu Sxg3iC0000 +{% else %} + +{% endif %} +``` + +When `custom_logo_base64` was stripped entirely, this condition always evaluated to `False`, causing the default logo to display instead of the custom uploaded logo. + +## Solution +Modified `sanitize_settings_for_user()` to add boolean flags for logo/favicon existence **after** the main sanitization loop. This allows templates to check if logos exist without exposing the actual base64 data. + +### Code Change +```python +def sanitize_settings_for_user(full_settings: dict) -> dict: + # ... existing sanitization logic ... + + # Add boolean flags for logo/favicon existence so templates can check without exposing base64 data + # These fields are stripped by the base64 filter above, but templates need to know if logos exist + if 'custom_logo_base64' in full_settings: + sanitized['custom_logo_base64'] = bool(full_settings.get('custom_logo_base64')) + if 'custom_logo_dark_base64' in full_settings: + sanitized['custom_logo_dark_base64'] = bool(full_settings.get('custom_logo_dark_base64')) + if 'custom_favicon_base64' in full_settings: + sanitized['custom_favicon_base64'] = bool(full_settings.get('custom_favicon_base64')) + + return sanitized +``` + +### How It Works +1. The sensitive base64 data is still stripped during the main loop +2. After sanitization, boolean flags are added: + - `True` if the logo exists (base64 string is non-empty) + - `False` if no logo is set (base64 string is empty) +3. Templates can still use `{% if app_settings.custom_logo_base64 %}` and it will correctly evaluate to `True` or `False` +4. The actual base64 data is never exposed to the frontend + +## Files Modified +- [functions_settings.py](../../application/single_app/functions_settings.py) - Modified `sanitize_settings_for_user()` function + +## Version +**Fixed in version:** 0.237.002 + +## Testing +A functional test was created: [test_custom_logo_sanitization_fix.py](../../functional_tests/test_custom_logo_sanitization_fix.py) + +### Test Cases +1. **Logo flags preserved as True** - When logos exist, boolean flags are `True` +2. **Logo flags preserved as False** - When logos are empty, boolean flags are `False` +3. **No spurious flags added** - If logo keys don't exist in settings, they're not added +4. **Template compatibility** - Boolean flags work correctly in Jinja2-style conditionals + +### Running the Test +```bash +cd functional_tests +python test_custom_logo_sanitization_fix.py +``` + +## Impact +This fix affects all pages that display the application logo: +- Landing/Index page +- Chat page +- Sidebar navigation (when left nav is enabled) +- Any other page using `base.html` that references logo settings + +## Security Considerations +- āœ… Actual base64 data is still never exposed to the frontend +- āœ… Only boolean True/False values are sent +- āœ… No sensitive data leakage +- āœ… Maintains the security intent of the original sanitization function diff --git a/docs/explanation/release_notes.md b/docs/explanation/release_notes.md index df88ebcd..53426cda 100644 --- a/docs/explanation/release_notes.md +++ b/docs/explanation/release_notes.md @@ -1,6 +1,18 @@ # Feature Release +### **(v0.237.002)** + +#### Bug Fixes + +* **Custom Logo Not Displaying Across App Fix** + * Fixed issue where custom logos uploaded via Admin Settings would only display on the admin page but not on other pages (chat, sidebar, landing page). + * **Root Cause**: The `sanitize_settings_for_user()` function was stripping `custom_logo_base64`, `custom_logo_dark_base64`, and `custom_favicon_base64` keys entirely because they contained "base64" (a sensitive term filter), preventing templates from detecting logo existence. + * **Solution**: Modified sanitization to add boolean flags for logo/favicon existence after filtering, allowing templates to check if logos exist without exposing actual base64 data. + * **Security**: Actual base64 data remains hidden from frontend; only True/False boolean values are exposed. + * **Files Modified**: `functions_settings.py` (`sanitize_settings_for_user()` function). + * (Ref: logo display, settings sanitization, template conditionals) + ### **(v0.237.001)** #### New Features diff --git a/functional_tests/test_custom_logo_sanitization_fix.py b/functional_tests/test_custom_logo_sanitization_fix.py new file mode 100644 index 00000000..419a7a1f --- /dev/null +++ b/functional_tests/test_custom_logo_sanitization_fix.py @@ -0,0 +1,172 @@ +#!/usr/bin/env python3 +""" +Functional test for custom logo sanitization fix. +Version: 0.237.002 +Implemented in: 0.237.002 + +This test ensures that custom logo boolean flags are preserved in sanitized settings +so templates can detect if custom logos exist without exposing the actual base64 data. + +Issue: When a logo was uploaded via admin settings, it was visible on the admin page +but not on other pages (like the chat page) because the `sanitize_settings_for_user` +function was stripping `custom_logo_base64`, `custom_logo_dark_base64`, and +`custom_favicon_base64` keys entirely, which templates use to conditionally display logos. + +Fix: Modified `sanitize_settings_for_user` to add boolean flags for logo/favicon +existence after sanitization, allowing templates to check `app_settings.custom_logo_base64` +(which will be True/False) without exposing the actual base64 data. +""" + +import sys +import os + +# Add the application directory to the path +sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', 'application', 'single_app')) + + +def test_sanitize_settings_preserves_logo_flags(): + """ + Test that sanitize_settings_for_user preserves boolean flags for logo existence. + """ + print("šŸ” Testing sanitize_settings_for_user preserves logo flags...") + + try: + from functions_settings import sanitize_settings_for_user + + # Test case 1: Settings with custom logos present + settings_with_logos = { + 'app_title': 'Test App', + 'show_logo': True, + 'custom_logo_base64': 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==', + 'custom_logo_dark_base64': 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==', + 'custom_favicon_base64': 'AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAQAAA==', + 'logo_version': 5, + 'some_api_key': 'secret-key-123', + 'azure_openai_key': 'another-secret-key', + } + + sanitized = sanitize_settings_for_user(settings_with_logos) + + # Verify non-sensitive fields are preserved + assert sanitized.get('app_title') == 'Test App', "app_title should be preserved" + assert sanitized.get('show_logo') == True, "show_logo should be preserved" + assert sanitized.get('logo_version') == 5, "logo_version should be preserved" + + # Verify sensitive keys are removed (api keys, secrets) + assert 'some_api_key' not in sanitized, "API keys should be removed" + assert 'azure_openai_key' not in sanitized, "Azure OpenAI key should be removed" + + # Verify logo flags are boolean True (not the actual base64 data) + assert sanitized.get('custom_logo_base64') == True, "custom_logo_base64 should be True (boolean flag)" + assert sanitized.get('custom_logo_dark_base64') == True, "custom_logo_dark_base64 should be True (boolean flag)" + assert sanitized.get('custom_favicon_base64') == True, "custom_favicon_base64 should be True (boolean flag)" + + # Verify the actual base64 data is NOT exposed + assert isinstance(sanitized.get('custom_logo_base64'), bool), "custom_logo_base64 should be a boolean, not a string" + + print("āœ… Test 1 passed: Logo flags are preserved as boolean True when logos exist") + + # Test case 2: Settings without custom logos + settings_without_logos = { + 'app_title': 'Test App', + 'show_logo': True, + 'custom_logo_base64': '', + 'custom_logo_dark_base64': '', + 'custom_favicon_base64': '', + } + + sanitized2 = sanitize_settings_for_user(settings_without_logos) + + # Verify logo flags are boolean False when logos are empty + assert sanitized2.get('custom_logo_base64') == False, "custom_logo_base64 should be False when empty" + assert sanitized2.get('custom_logo_dark_base64') == False, "custom_logo_dark_base64 should be False when empty" + assert sanitized2.get('custom_favicon_base64') == False, "custom_favicon_base64 should be False when empty" + + print("āœ… Test 2 passed: Logo flags are False when logos are empty/not set") + + # Test case 3: Settings without logo keys at all + settings_no_logo_keys = { + 'app_title': 'Test App', + 'show_logo': False, + } + + sanitized3 = sanitize_settings_for_user(settings_no_logo_keys) + + # Verify logo keys are not added if they didn't exist + assert 'custom_logo_base64' not in sanitized3, "custom_logo_base64 should not be added if not in original settings" + + print("āœ… Test 3 passed: Logo flags are not added if keys not in original settings") + + print("\nāœ… All tests passed!") + return True + + except AssertionError as e: + print(f"āŒ Assertion failed: {e}") + import traceback + traceback.print_exc() + return False + except Exception as e: + print(f"āŒ Test failed with exception: {e}") + import traceback + traceback.print_exc() + return False + + +def test_template_compatibility(): + """ + Test that the boolean flags work correctly in Jinja2-style conditionals. + """ + print("\nšŸ” Testing template compatibility with boolean flags...") + + try: + from functions_settings import sanitize_settings_for_user + + settings = { + 'custom_logo_base64': 'some-base64-data', + 'custom_logo_dark_base64': '', + } + + sanitized = sanitize_settings_for_user(settings) + + # Simulate Jinja2 conditional: {% if app_settings.custom_logo_base64 %} + if sanitized.get('custom_logo_base64'): + light_logo_condition = "show custom light logo" + else: + light_logo_condition = "show default light logo" + + assert light_logo_condition == "show custom light logo", "Light logo should use custom" + + # Simulate Jinja2 conditional: {% if app_settings.custom_logo_dark_base64 %} + if sanitized.get('custom_logo_dark_base64'): + dark_logo_condition = "show custom dark logo" + else: + dark_logo_condition = "show default dark logo" + + assert dark_logo_condition == "show default dark logo", "Dark logo should use default (empty base64)" + + print("āœ… Template compatibility test passed!") + return True + + except Exception as e: + print(f"āŒ Template compatibility test failed: {e}") + import traceback + traceback.print_exc() + return False + + +if __name__ == "__main__": + results = [] + + print("=" * 60) + print("Custom Logo Sanitization Fix - Functional Tests") + print("=" * 60) + + results.append(test_sanitize_settings_preserves_logo_flags()) + results.append(test_template_compatibility()) + + print("\n" + "=" * 60) + success = all(results) + print(f"šŸ“Š Results: {sum(results)}/{len(results)} tests passed") + print("=" * 60) + + sys.exit(0 if success else 1) From 9c7aad3a81d11a36288ac4dea95649ac2fc2928d Mon Sep 17 00:00:00 2001 From: Paul Lizer Date: Mon, 26 Jan 2026 15:45:05 -0500 Subject: [PATCH 3/4] added 2,3,4,5,6,14 days to rentention policy --- application/single_app/config.py | 2 +- .../single_app/templates/admin_settings.html | 36 +++++++++++++++++++ .../single_app/templates/control_center.html | 24 +++++++++++++ application/single_app/templates/profile.html | 12 +++++++ 4 files changed, 73 insertions(+), 1 deletion(-) diff --git a/application/single_app/config.py b/application/single_app/config.py index 12906ce8..9a5c892f 100644 --- a/application/single_app/config.py +++ b/application/single_app/config.py @@ -88,7 +88,7 @@ EXECUTOR_TYPE = 'thread' EXECUTOR_MAX_WORKERS = 30 SESSION_TYPE = 'filesystem' -VERSION = "0.237.001" +VERSION = "0.237.003" SECRET_KEY = os.getenv('SECRET_KEY', 'dev-secret-key-change-in-production') diff --git a/application/single_app/templates/admin_settings.html b/application/single_app/templates/admin_settings.html index 7ef20f2d..70edcc45 100644 --- a/application/single_app/templates/admin_settings.html +++ b/application/single_app/templates/admin_settings.html @@ -2463,8 +2463,14 @@
Default Retention Policies + + + + + + @@ -2479,8 +2485,14 @@
Default Retention Policies + + + + + + @@ -2502,8 +2514,14 @@
Default Retention Policies + + + + + + @@ -2518,8 +2536,14 @@
Default Retention Policies + + + + + + @@ -2541,8 +2565,14 @@
Default Retention Policies + + + + + + @@ -2557,8 +2587,14 @@
Default Retention Policies + + + + + + diff --git a/application/single_app/templates/control_center.html b/application/single_app/templates/control_center.html index 853b4631..7a86d961 100644 --- a/application/single_app/templates/control_center.html +++ b/application/single_app/templates/control_center.html @@ -1670,8 +1670,14 @@
Retention PolicyUsing organization default + + + + + + @@ -1687,8 +1693,14 @@
Retention PolicyUsing organization default + + + + + + @@ -2287,8 +2299,14 @@
Retention PolicyUsing organization default + + + + + + @@ -2304,8 +2322,14 @@
Retention PolicyUsing organization default + + + + + + diff --git a/application/single_app/templates/profile.html b/application/single_app/templates/profile.html index e5a62887..2ab543f7 100644 --- a/application/single_app/templates/profile.html +++ b/application/single_app/templates/profile.html @@ -319,8 +319,14 @@
Retention Policy Sett + + + + + + @@ -338,8 +344,14 @@
Retention Policy Sett + + + + + + From ab4359e06c634b0888cd9876a2f5c4c60f950561 Mon Sep 17 00:00:00 2001 From: Paul Lizer Date: Mon, 26 Jan 2026 15:47:40 -0500 Subject: [PATCH 4/4] added retention policy time updates --- .../CUSTOM_LOGO_NOT_DISPLAYING_FIX.md | 0 docs/explanation/release_notes.md | 12 +++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) rename docs/explanation/fixes/{v0.237.002 => v0.237.003}/CUSTOM_LOGO_NOT_DISPLAYING_FIX.md (100%) diff --git a/docs/explanation/fixes/v0.237.002/CUSTOM_LOGO_NOT_DISPLAYING_FIX.md b/docs/explanation/fixes/v0.237.003/CUSTOM_LOGO_NOT_DISPLAYING_FIX.md similarity index 100% rename from docs/explanation/fixes/v0.237.002/CUSTOM_LOGO_NOT_DISPLAYING_FIX.md rename to docs/explanation/fixes/v0.237.003/CUSTOM_LOGO_NOT_DISPLAYING_FIX.md diff --git a/docs/explanation/release_notes.md b/docs/explanation/release_notes.md index 53426cda..3b3de6e6 100644 --- a/docs/explanation/release_notes.md +++ b/docs/explanation/release_notes.md @@ -1,7 +1,17 @@ # Feature Release -### **(v0.237.002)** +### **(v0.237.003)** + +#### New Features + +* **Extended Retention Policy Timeline Options** + * Added additional granular retention period options for conversations and documents across all workspace types. + * **New Options**: 2 days, 3 days, 4 days, 6 days, 7 days (1 week), and 14 days (2 weeks). + * **Full Option Set**: 1, 2, 3, 4, 5, 6, 7 (1 week), 10, 14 (2 weeks), 21 (3 weeks), 30, 60, 90 (3 months), 180 (6 months), 365 (1 year), 730 (2 years) days. + * **Scope**: Available in Admin Settings (organization defaults), Profile page (personal settings), and Control Center (group/public workspace management). + * **Files Modified**: `admin_settings.html`, `profile.html`, `control_center.html`. + * (Ref: retention policy configuration, workspace retention settings, granular time periods) #### Bug Fixes