Fossil SCM

Improved captcha screen. Less clutter. Easier for first-time visitors to digest.

drh 2025-08-14 19:35 trunk
Commit 6c8c93a5f7198d565b5e3e025b44c8c74bb0bf4017320d521200d6c14e04b4a2
1 file changed +58 -31
+58 -31
--- src/login.c
+++ src/login.c
@@ -590,11 +590,19 @@
590590
fossil_redirect_to_https_if_needed(1);
591591
sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
592592
constant_time_cmp_function, 0, 0);
593593
zUsername = P("u");
594594
zPasswd = P("p");
595
+
596
+ /* If the anonFlag is set, that means rework the web-page to make it
597
+ ** a more user-friendly captcha. Extraneous text and boxes are omitted.
598
+ ** The user has just the captcha image and an entry box and a "Verify"
599
+ ** button. Underneath is the same login page for user "anonymous", just
600
+ ** displayed in an easier to digest format for one-time visitors.
601
+ */
595602
anonFlag = g.zLogin==0 && PB("anon");
603
+
596604
/* Handle log-out requests */
597605
if( P("out") && cgi_csrf_safe(2) ){
598606
login_clear_login_data();
599607
login_redirect_to_g();
600608
return;
@@ -731,12 +739,12 @@
731739
zAbbrev[i] = 0;
732740
if( g.zLogin ){
733741
@ <p>Use a different login with greater privilege than <b>%h(g.zLogin)</b>
734742
@ to access <b>%h(zAbbrev)</b>.
735743
}else if( anonFlag ){
736
- @ <p>Login as <b>anonymous</b> or any named user
737
- @ to access page <b>%h(zAbbrev)</b>.
744
+ @ <p><b>Verify that you are human by typing in the 8-character text
745
+ @ password shown below.</b></p>
738746
}else{
739747
@ <p>Login as a named user to access page <b>%h(zAbbrev)</b>.
740748
}
741749
fossil_free(zAbbrev);
742750
}
@@ -751,10 +759,11 @@
751759
if( zGoto ){
752760
@ <input type="hidden" name="g" value="%h(zGoto)">
753761
}
754762
if( anonFlag ){
755763
@ <input type="hidden" name="anon" value="1">
764
+ @ <input type="hidden" name="u" value="anonymous">
756765
}
757766
if( g.zLogin ){
758767
@ <p>Currently logged in as <b>%h(g.zLogin)</b>.
759768
@ <input type="submit" name="out" value="Logout" autofocus></p>
760769
@ </form>
@@ -766,11 +775,11 @@
766775
" AND cap!=''");
767776
}else{
768777
zAnonPw = 0;
769778
}
770779
@ <table class="login_out">
771
- if( P("HTTPS")==0 ){
780
+ if( P("HTTPS")==0 && !anonFlag ){
772781
@ <tr><td class="form_label">Warning:</td>
773782
@ <td><span class='securityWarning'>
774783
@ Login information, including the password,
775784
@ will be sent in the clear over an unencrypted connection.
776785
if( !g.sslNotAvailable ){
@@ -777,41 +786,55 @@
777786
@ Consider logging in at
778787
@ <a href='%s(g.zHttpsURL)'>%h(g.zHttpsURL)</a> instead.
779788
}
780789
@ </span></td></tr>
781790
}
782
- @ <tr>
783
- @ <td class="form_label" id="userlabel1">User ID:</td>
784
- @ <td><input type="text" id="u" aria-labelledby="userlabel1" name="u" \
785
- @ size="30" value="%s(anonFlag?"anonymous":"")" autofocus></td>
786
- @ </tr>
791
+ if( !anonFlag ){
792
+ @ <tr>
793
+ @ <td class="form_label" id="userlabel1">User ID:</td>
794
+ @ <td><input type="text" id="u" aria-labelledby="userlabel1" name="u" \
795
+ @ size="30" value="" autofocus></td>
796
+ @ </tr>
797
+ }
787798
@ <tr>
788799
@ <td class="form_label" id="pswdlabel">Password:</td>
789800
@ <td><input aria-labelledby="pswdlabel" type="password" id="p" \
790
- @ name="p" value="" size="30">\
791
- if( zAnonPw && !noAnon ){
801
+ @ name="p" value="" size="30">
802
+ if( anonFlag ){
803
+ @ </td></tr>
804
+ @ <tr>
805
+ @ <td></td><td>\
806
+ captcha_speakit_button(uSeed, "Read the password out loud");
807
+ }else if( zAnonPw && !noAnon ){
792808
captcha_speakit_button(uSeed, "Speak password for \"anonymous\"");
793809
}
794810
@ </td>
795811
@ </tr>
796
- @ <tr>
797
- @ <td></td>
798
- @ <td><input type="checkbox" name="remember" value="1" \
799
- @ id="remember-me" %s(rememberMe ? "checked=\"checked\"" : "")>
800
- @ <label for="remember-me">Remember me?</label></td>
801
- @ </tr>
802
- @ <tr>
803
- @ <td></td>
804
- @ <td><input type="submit" name="in" value="Login">
805
- @ </tr>
806
- if( !noAnon && login_self_register_available(0) ){
812
+ if( !anonFlag ){
813
+ @ <tr>
814
+ @ <td></td>
815
+ @ <td><input type="checkbox" name="remember" value="1" \
816
+ @ id="remember-me" %s(rememberMe ? "checked=\"checked\"" : "")>
817
+ @ <label for="remember-me">Remember me?</label></td>
818
+ @ </tr>
819
+ @ <tr>
820
+ @ <td></td>
821
+ @ <td><input type="submit" name="in" value="Login">
822
+ @ </tr>
823
+ }else{
824
+ @ <tr>
825
+ @ <td></td>
826
+ @ <td><input type="submit" name="in" value="Verify that I am human">
827
+ @ </tr>
828
+ }
829
+ if( !anonFlag && !noAnon && login_self_register_available(0) ){
807830
@ <tr>
808831
@ <td></td>
809832
@ <td><input type="submit" name="self" value="Create A New Account">
810833
@ </tr>
811834
}
812
- if( login_self_password_reset_available() ){
835
+ if( !anonFlag && login_self_password_reset_available() ){
813836
@ <tr>
814837
@ <td></td>
815838
@ <td><input type="submit" name="pwreset" value="Reset My Password">
816839
@ </tr>
817840
}
@@ -820,27 +843,29 @@
820843
const char *zDecoded = captcha_decode(uSeed, 0);
821844
int bAutoCaptcha = db_get_boolean("auto-captcha", 0);
822845
char *zCaptcha = captcha_render(zDecoded);
823846
824847
@ <p><input type="hidden" name="cs" value="%u(uSeed)">
825
- @ Visitors may enter <b>anonymous</b> as the user-ID with
826
- @ the 8-character hexadecimal password shown below:</p>
848
+ if( !anonFlag ){
849
+ @ Visitors may enter <b>anonymous</b> as the user-ID with
850
+ @ the 8-character hexadecimal password shown below:</p>
851
+ }
827852
@ <div class="captcha"><table class="captcha"><tr><td>\
828853
@ <pre class="captcha">
829854
@ %h(zCaptcha)
830855
@ </pre></td></tr></table>
831
- if( bAutoCaptcha ) {
856
+ if( bAutoCaptcha && !anonFlag ) {
832857
@ <input type="button" value="Fill out captcha" id='autofillButton' \
833858
@ data-af='%s(zDecoded)'>
834859
builtin_request_js("login.js");
835860
}
836861
@ </div>
837862
free(zCaptcha);
838863
}
839864
@ </form>
840865
}
841
- if( login_is_individual() ){
866
+ if( login_is_individual() && !anonFlag ){
842867
if( g.perm.EmailAlert && alert_enabled() ){
843868
@ <hr>
844869
@ <p>Configure <a href="%R/alerts">Email Alerts</a>
845870
@ for user <b>%h(g.zLogin)</b></p>
846871
}
@@ -848,15 +873,17 @@
848873
@ <hr><p>
849874
@ <a href="%R/timeline?ss=v&y=f&vfx&u=%t(g.zLogin)">Forum
850875
@ post timeline</a> for user <b>%h(g.zLogin)</b></p>
851876
}
852877
}
853
- @ <hr><p>
854
- @ Select your preferred <a href="%R/skins">site skin</a>.
855
- @ </p>
856
- @ <hr><p>
857
- @ Manage your <a href="%R/cookies">cookies</a>.</p>
878
+ if( !anonFlag ){
879
+ @ <hr><p>
880
+ @ Select your preferred <a href="%R/skins">site skin</a>.
881
+ @ </p>
882
+ @ <hr><p>
883
+ @ Manage your <a href="%R/cookies">cookies</a>.</p>
884
+ }
858885
if( login_is_individual() ){
859886
if( g.perm.Password ){
860887
char *zRPW = fossil_random_password(12);
861888
@ <hr>
862889
@ <p>Change Password for user <b>%h(g.zLogin)</b>:</p>
863890
--- src/login.c
+++ src/login.c
@@ -590,11 +590,19 @@
590 fossil_redirect_to_https_if_needed(1);
591 sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
592 constant_time_cmp_function, 0, 0);
593 zUsername = P("u");
594 zPasswd = P("p");
 
 
 
 
 
 
 
595 anonFlag = g.zLogin==0 && PB("anon");
 
596 /* Handle log-out requests */
597 if( P("out") && cgi_csrf_safe(2) ){
598 login_clear_login_data();
599 login_redirect_to_g();
600 return;
@@ -731,12 +739,12 @@
731 zAbbrev[i] = 0;
732 if( g.zLogin ){
733 @ <p>Use a different login with greater privilege than <b>%h(g.zLogin)</b>
734 @ to access <b>%h(zAbbrev)</b>.
735 }else if( anonFlag ){
736 @ <p>Login as <b>anonymous</b> or any named user
737 @ to access page <b>%h(zAbbrev)</b>.
738 }else{
739 @ <p>Login as a named user to access page <b>%h(zAbbrev)</b>.
740 }
741 fossil_free(zAbbrev);
742 }
@@ -751,10 +759,11 @@
751 if( zGoto ){
752 @ <input type="hidden" name="g" value="%h(zGoto)">
753 }
754 if( anonFlag ){
755 @ <input type="hidden" name="anon" value="1">
 
756 }
757 if( g.zLogin ){
758 @ <p>Currently logged in as <b>%h(g.zLogin)</b>.
759 @ <input type="submit" name="out" value="Logout" autofocus></p>
760 @ </form>
@@ -766,11 +775,11 @@
766 " AND cap!=''");
767 }else{
768 zAnonPw = 0;
769 }
770 @ <table class="login_out">
771 if( P("HTTPS")==0 ){
772 @ <tr><td class="form_label">Warning:</td>
773 @ <td><span class='securityWarning'>
774 @ Login information, including the password,
775 @ will be sent in the clear over an unencrypted connection.
776 if( !g.sslNotAvailable ){
@@ -777,41 +786,55 @@
777 @ Consider logging in at
778 @ <a href='%s(g.zHttpsURL)'>%h(g.zHttpsURL)</a> instead.
779 }
780 @ </span></td></tr>
781 }
782 @ <tr>
783 @ <td class="form_label" id="userlabel1">User ID:</td>
784 @ <td><input type="text" id="u" aria-labelledby="userlabel1" name="u" \
785 @ size="30" value="%s(anonFlag?"anonymous":"")" autofocus></td>
786 @ </tr>
 
 
787 @ <tr>
788 @ <td class="form_label" id="pswdlabel">Password:</td>
789 @ <td><input aria-labelledby="pswdlabel" type="password" id="p" \
790 @ name="p" value="" size="30">\
791 if( zAnonPw && !noAnon ){
 
 
 
 
 
792 captcha_speakit_button(uSeed, "Speak password for \"anonymous\"");
793 }
794 @ </td>
795 @ </tr>
796 @ <tr>
797 @ <td></td>
798 @ <td><input type="checkbox" name="remember" value="1" \
799 @ id="remember-me" %s(rememberMe ? "checked=\"checked\"" : "")>
800 @ <label for="remember-me">Remember me?</label></td>
801 @ </tr>
802 @ <tr>
803 @ <td></td>
804 @ <td><input type="submit" name="in" value="Login">
805 @ </tr>
806 if( !noAnon && login_self_register_available(0) ){
 
 
 
 
 
 
 
807 @ <tr>
808 @ <td></td>
809 @ <td><input type="submit" name="self" value="Create A New Account">
810 @ </tr>
811 }
812 if( login_self_password_reset_available() ){
813 @ <tr>
814 @ <td></td>
815 @ <td><input type="submit" name="pwreset" value="Reset My Password">
816 @ </tr>
817 }
@@ -820,27 +843,29 @@
820 const char *zDecoded = captcha_decode(uSeed, 0);
821 int bAutoCaptcha = db_get_boolean("auto-captcha", 0);
822 char *zCaptcha = captcha_render(zDecoded);
823
824 @ <p><input type="hidden" name="cs" value="%u(uSeed)">
825 @ Visitors may enter <b>anonymous</b> as the user-ID with
826 @ the 8-character hexadecimal password shown below:</p>
 
 
827 @ <div class="captcha"><table class="captcha"><tr><td>\
828 @ <pre class="captcha">
829 @ %h(zCaptcha)
830 @ </pre></td></tr></table>
831 if( bAutoCaptcha ) {
832 @ <input type="button" value="Fill out captcha" id='autofillButton' \
833 @ data-af='%s(zDecoded)'>
834 builtin_request_js("login.js");
835 }
836 @ </div>
837 free(zCaptcha);
838 }
839 @ </form>
840 }
841 if( login_is_individual() ){
842 if( g.perm.EmailAlert && alert_enabled() ){
843 @ <hr>
844 @ <p>Configure <a href="%R/alerts">Email Alerts</a>
845 @ for user <b>%h(g.zLogin)</b></p>
846 }
@@ -848,15 +873,17 @@
848 @ <hr><p>
849 @ <a href="%R/timeline?ss=v&y=f&vfx&u=%t(g.zLogin)">Forum
850 @ post timeline</a> for user <b>%h(g.zLogin)</b></p>
851 }
852 }
853 @ <hr><p>
854 @ Select your preferred <a href="%R/skins">site skin</a>.
855 @ </p>
856 @ <hr><p>
857 @ Manage your <a href="%R/cookies">cookies</a>.</p>
 
 
858 if( login_is_individual() ){
859 if( g.perm.Password ){
860 char *zRPW = fossil_random_password(12);
861 @ <hr>
862 @ <p>Change Password for user <b>%h(g.zLogin)</b>:</p>
863
--- src/login.c
+++ src/login.c
@@ -590,11 +590,19 @@
590 fossil_redirect_to_https_if_needed(1);
591 sqlite3_create_function(g.db, "constant_time_cmp", 2, SQLITE_UTF8, 0,
592 constant_time_cmp_function, 0, 0);
593 zUsername = P("u");
594 zPasswd = P("p");
595
596 /* If the anonFlag is set, that means rework the web-page to make it
597 ** a more user-friendly captcha. Extraneous text and boxes are omitted.
598 ** The user has just the captcha image and an entry box and a "Verify"
599 ** button. Underneath is the same login page for user "anonymous", just
600 ** displayed in an easier to digest format for one-time visitors.
601 */
602 anonFlag = g.zLogin==0 && PB("anon");
603
604 /* Handle log-out requests */
605 if( P("out") && cgi_csrf_safe(2) ){
606 login_clear_login_data();
607 login_redirect_to_g();
608 return;
@@ -731,12 +739,12 @@
739 zAbbrev[i] = 0;
740 if( g.zLogin ){
741 @ <p>Use a different login with greater privilege than <b>%h(g.zLogin)</b>
742 @ to access <b>%h(zAbbrev)</b>.
743 }else if( anonFlag ){
744 @ <p><b>Verify that you are human by typing in the 8-character text
745 @ password shown below.</b></p>
746 }else{
747 @ <p>Login as a named user to access page <b>%h(zAbbrev)</b>.
748 }
749 fossil_free(zAbbrev);
750 }
@@ -751,10 +759,11 @@
759 if( zGoto ){
760 @ <input type="hidden" name="g" value="%h(zGoto)">
761 }
762 if( anonFlag ){
763 @ <input type="hidden" name="anon" value="1">
764 @ <input type="hidden" name="u" value="anonymous">
765 }
766 if( g.zLogin ){
767 @ <p>Currently logged in as <b>%h(g.zLogin)</b>.
768 @ <input type="submit" name="out" value="Logout" autofocus></p>
769 @ </form>
@@ -766,11 +775,11 @@
775 " AND cap!=''");
776 }else{
777 zAnonPw = 0;
778 }
779 @ <table class="login_out">
780 if( P("HTTPS")==0 && !anonFlag ){
781 @ <tr><td class="form_label">Warning:</td>
782 @ <td><span class='securityWarning'>
783 @ Login information, including the password,
784 @ will be sent in the clear over an unencrypted connection.
785 if( !g.sslNotAvailable ){
@@ -777,41 +786,55 @@
786 @ Consider logging in at
787 @ <a href='%s(g.zHttpsURL)'>%h(g.zHttpsURL)</a> instead.
788 }
789 @ </span></td></tr>
790 }
791 if( !anonFlag ){
792 @ <tr>
793 @ <td class="form_label" id="userlabel1">User ID:</td>
794 @ <td><input type="text" id="u" aria-labelledby="userlabel1" name="u" \
795 @ size="30" value="" autofocus></td>
796 @ </tr>
797 }
798 @ <tr>
799 @ <td class="form_label" id="pswdlabel">Password:</td>
800 @ <td><input aria-labelledby="pswdlabel" type="password" id="p" \
801 @ name="p" value="" size="30">
802 if( anonFlag ){
803 @ </td></tr>
804 @ <tr>
805 @ <td></td><td>\
806 captcha_speakit_button(uSeed, "Read the password out loud");
807 }else if( zAnonPw && !noAnon ){
808 captcha_speakit_button(uSeed, "Speak password for \"anonymous\"");
809 }
810 @ </td>
811 @ </tr>
812 if( !anonFlag ){
813 @ <tr>
814 @ <td></td>
815 @ <td><input type="checkbox" name="remember" value="1" \
816 @ id="remember-me" %s(rememberMe ? "checked=\"checked\"" : "")>
817 @ <label for="remember-me">Remember me?</label></td>
818 @ </tr>
819 @ <tr>
820 @ <td></td>
821 @ <td><input type="submit" name="in" value="Login">
822 @ </tr>
823 }else{
824 @ <tr>
825 @ <td></td>
826 @ <td><input type="submit" name="in" value="Verify that I am human">
827 @ </tr>
828 }
829 if( !anonFlag && !noAnon && login_self_register_available(0) ){
830 @ <tr>
831 @ <td></td>
832 @ <td><input type="submit" name="self" value="Create A New Account">
833 @ </tr>
834 }
835 if( !anonFlag && login_self_password_reset_available() ){
836 @ <tr>
837 @ <td></td>
838 @ <td><input type="submit" name="pwreset" value="Reset My Password">
839 @ </tr>
840 }
@@ -820,27 +843,29 @@
843 const char *zDecoded = captcha_decode(uSeed, 0);
844 int bAutoCaptcha = db_get_boolean("auto-captcha", 0);
845 char *zCaptcha = captcha_render(zDecoded);
846
847 @ <p><input type="hidden" name="cs" value="%u(uSeed)">
848 if( !anonFlag ){
849 @ Visitors may enter <b>anonymous</b> as the user-ID with
850 @ the 8-character hexadecimal password shown below:</p>
851 }
852 @ <div class="captcha"><table class="captcha"><tr><td>\
853 @ <pre class="captcha">
854 @ %h(zCaptcha)
855 @ </pre></td></tr></table>
856 if( bAutoCaptcha && !anonFlag ) {
857 @ <input type="button" value="Fill out captcha" id='autofillButton' \
858 @ data-af='%s(zDecoded)'>
859 builtin_request_js("login.js");
860 }
861 @ </div>
862 free(zCaptcha);
863 }
864 @ </form>
865 }
866 if( login_is_individual() && !anonFlag ){
867 if( g.perm.EmailAlert && alert_enabled() ){
868 @ <hr>
869 @ <p>Configure <a href="%R/alerts">Email Alerts</a>
870 @ for user <b>%h(g.zLogin)</b></p>
871 }
@@ -848,15 +873,17 @@
873 @ <hr><p>
874 @ <a href="%R/timeline?ss=v&y=f&vfx&u=%t(g.zLogin)">Forum
875 @ post timeline</a> for user <b>%h(g.zLogin)</b></p>
876 }
877 }
878 if( !anonFlag ){
879 @ <hr><p>
880 @ Select your preferred <a href="%R/skins">site skin</a>.
881 @ </p>
882 @ <hr><p>
883 @ Manage your <a href="%R/cookies">cookies</a>.</p>
884 }
885 if( login_is_individual() ){
886 if( g.perm.Password ){
887 char *zRPW = fossil_random_password(12);
888 @ <hr>
889 @ <p>Change Password for user <b>%h(g.zLogin)</b>:</p>
890

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button