Fossil SCM

Add support for [/wiki?name=branch/rptview-submenu-paralink&p|submenu parametric hyperlinks] for [/help?cmd=/rptview|/rptview] and [/help?cmd=/wiki|/wiki] pages.

george 2021-06-12 18:43 trunk merge
Commit 9690fc39dc938f4bb6f3acfd634c62252950424d7d6a73b3f741201f462f8ec7
+12 -2
--- src/report.c
+++ src/report.c
@@ -972,14 +972,22 @@
972972
}
973973
974974
/*
975975
** WEBPAGE: rptview
976976
**
977
-** Generate a report. The rn query parameter is the report number
978
-** corresponding to REPORTFMT.RN. If the tablist query parameter exists,
977
+** Generate a report. The "rn" query parameter is the report number
978
+** corresponding to REPORTFMT.RN. If the "tablist" query parameter exists,
979979
** then the output consists of lines of tab-separated fields instead of
980980
** an HTML table.
981
+**
982
+** Submenu of the /rptview page can be extended with additional
983
+** hyperlinks by providing query parameter(s) of the form rvsmplXY=Z.
984
+** Optional ending XY consists of a digit X from the set {1,2,3,4,5}
985
+** and an optional letter Y that (if present) must be either 'a' or 's'.
986
+** Mandatory Z is a repo-local hyperlink's target (wihout leading '/').
987
+**
988
+** For details see the wiki page "branch/rptview-submenu-paralink".
981989
*/
982990
void rptview_page(void){
983991
int count = 0;
984992
int rn, rc;
985993
char *zSql;
@@ -1045,10 +1053,12 @@
10451053
style_submenu_element("Reports","%R/reportlist?%s",zQS);
10461054
} else {
10471055
style_submenu_element("Raw","%R/%s?tablist=1",g.zPath);
10481056
style_submenu_element("Reports","%R/reportlist");
10491057
}
1058
+ style_submenu_parametric("rv");
1059
+
10501060
if( g.perm.Admin
10511061
|| (g.perm.TktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){
10521062
style_submenu_element("Edit", "rptedit?rn=%d", rn);
10531063
}
10541064
if( g.perm.TktFmt ){
10551065
--- src/report.c
+++ src/report.c
@@ -972,14 +972,22 @@
972 }
973
974 /*
975 ** WEBPAGE: rptview
976 **
977 ** Generate a report. The rn query parameter is the report number
978 ** corresponding to REPORTFMT.RN. If the tablist query parameter exists,
979 ** then the output consists of lines of tab-separated fields instead of
980 ** an HTML table.
 
 
 
 
 
 
 
 
981 */
982 void rptview_page(void){
983 int count = 0;
984 int rn, rc;
985 char *zSql;
@@ -1045,10 +1053,12 @@
1045 style_submenu_element("Reports","%R/reportlist?%s",zQS);
1046 } else {
1047 style_submenu_element("Raw","%R/%s?tablist=1",g.zPath);
1048 style_submenu_element("Reports","%R/reportlist");
1049 }
 
 
1050 if( g.perm.Admin
1051 || (g.perm.TktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){
1052 style_submenu_element("Edit", "rptedit?rn=%d", rn);
1053 }
1054 if( g.perm.TktFmt ){
1055
--- src/report.c
+++ src/report.c
@@ -972,14 +972,22 @@
972 }
973
974 /*
975 ** WEBPAGE: rptview
976 **
977 ** Generate a report. The "rn" query parameter is the report number
978 ** corresponding to REPORTFMT.RN. If the "tablist" query parameter exists,
979 ** then the output consists of lines of tab-separated fields instead of
980 ** an HTML table.
981 **
982 ** Submenu of the /rptview page can be extended with additional
983 ** hyperlinks by providing query parameter(s) of the form rvsmplXY=Z.
984 ** Optional ending XY consists of a digit X from the set {1,2,3,4,5}
985 ** and an optional letter Y that (if present) must be either 'a' or 's'.
986 ** Mandatory Z is a repo-local hyperlink's target (wihout leading '/').
987 **
988 ** For details see the wiki page "branch/rptview-submenu-paralink".
989 */
990 void rptview_page(void){
991 int count = 0;
992 int rn, rc;
993 char *zSql;
@@ -1045,10 +1053,12 @@
1053 style_submenu_element("Reports","%R/reportlist?%s",zQS);
1054 } else {
1055 style_submenu_element("Raw","%R/%s?tablist=1",g.zPath);
1056 style_submenu_element("Reports","%R/reportlist");
1057 }
1058 style_submenu_parametric("rv");
1059
1060 if( g.perm.Admin
1061 || (g.perm.TktFmt && g.zLogin && fossil_strcmp(g.zLogin,zOwner)==0) ){
1062 style_submenu_element("Edit", "rptedit?rn=%d", rn);
1063 }
1064 if( g.perm.TktFmt ){
1065
+96 -1
--- src/style.c
+++ src/style.c
@@ -32,10 +32,11 @@
3232
** style_submenu_entry()
3333
** style_submenu_checkbox()
3434
** style_submenu_binary()
3535
** style_submenu_multichoice()
3636
** style_submenu_sql()
37
+** style_submenu_parametric()
3738
**
3839
** prior to calling style_finish_page(). The style_finish_page() routine
3940
** will generate the appropriate HTML text just below the main
4041
** menu.
4142
*/
@@ -329,10 +330,104 @@
329330
aSubmenuCtrl[nSubmenuCtrl].eVisible = STYLE_NORMAL;
330331
aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI;
331332
nSubmenuCtrl++;
332333
}
333334
}
335
+
336
+/* Add hyperlinks depending on the existence and values of special
337
+** parameters in the request's query string. The names of a query's
338
+** parameters that are investigated are obtainted by concatenation of
339
+** the caller-provided zPrefix with suffix "smplXY", where optional
340
+** ending XY consists of a digit X from the set {1,2,3,4,5} and an
341
+** optional letter Y which (if present) must be either 'a' or 's'.
342
+** zPrefix must start with a lowercase letter,
343
+** be short and have no strange characters. Parameter's value
344
+** is well-formed if its first filepath segment (separated by '/')
345
+** has no strange characters. Malformed values are silently ignored.
346
+**
347
+** The text for the resulting submenu label equals to the value of the
348
+** parameter modulus some prettification for better UX:
349
+** 1) If a parameter's value starts with a lowercase letter and
350
+** contains '/' then it goes unchanged into the user-visible label.
351
+** 2a) If the first letter is uppercase then the label is
352
+** truncated at the first '/' (if any),
353
+** 2b) otherwise the first letter is capitalized.
354
+** 3) Underscores in the first path segment are replaced with spaces.
355
+** 4) If the resulting label starts with an uppercase letter
356
+** then it is prepended with "✧" symbol for explicit distinction
357
+** from the built-in labels
358
+**
359
+** Important security-related note:
360
+** zLabel and zLink are formatted using %s because it is expected that
361
+** style_finish_page() provides propper escaping via %h format.
362
+*/
363
+void style_submenu_parametric(
364
+ const char *zPrefix /* common prefix of the query parameters names */
365
+){
366
+ static const char *suffix = "smpl"; /* common suffix for param names */
367
+ static const short sfxlen = 4; /* length of the above suffix */
368
+ static const char sfxext[3] = {'a','s',0}; /* extra suffix ending */
369
+ const char *zQS; /* QUERY_STRING */
370
+ char zN[32]; /* buffer for parameter names to probe */
371
+ short i,j,l;
372
+
373
+ /* zPrefix must be tidy and short; also filter out ENV/CGI variables */
374
+ assert( zPrefix != 0 && fossil_islower(zPrefix[0]) );
375
+ l = strnlen( zPrefix, sizeof(zN) );
376
+ assert( l+sfxlen+3 <= sizeof(zN) );
377
+ assert( fossil_no_strange_characters(zPrefix) );
378
+ /* concatenate zPrefix and suffix */
379
+ strcpy( zN, zPrefix );
380
+ strcpy( zN + l, suffix );
381
+ l += sfxlen;
382
+ zN[l+2] = 0; /* nul-terminator after ...smplXY suffix */
383
+ zQS = PD("QUERY_STRING","");
384
+ for( i = 0; i <= 5; i++ ){
385
+ zN[l] = ( i == 0 ? 0 : '0' + i ); /* ...smpl instead of ...smpl0 */
386
+ for( j = (i ? 0 : sizeof(sfxext)-1); j < sizeof(sfxext); j++ ){
387
+ const char *zV, *z;
388
+ zN[l+1] = sfxext[j];
389
+ zV = PD(zN,"");
390
+ if( zV[0] == 0 || zV[0] == '/' || zV[0] == '_' || zV[0] == '-' ){
391
+ continue;
392
+ }
393
+ /* require the first path segment to be unfancy ASCII string */
394
+ for( z = zV; z[0] && z[0] != '/' ;){
395
+ if( fossil_isalnum(z[0]) || z[0]=='_' || z[0]=='-' ) z++;
396
+ else break;
397
+ }
398
+ if( z[0] != 0 && z[0] != '/' )
399
+ continue;
400
+ assert( nSubmenu < count(aSubmenu) );
401
+ if(fossil_islower(zV[0]) && z[0]=='/'){
402
+ aSubmenu[nSubmenu].zLabel = mprintf( "%s",zV); /* memory leak? */
403
+ }else{
404
+ /* prepend a label with an unobtrusive symbol that "sorts-last";
405
+ ** this clearly distincts it from the built-in elements */
406
+ static const char *mark = "✧";
407
+ char *z = mprintf("%s%s",mark,zV);
408
+ aSubmenu[nSubmenu].zLabel = z;
409
+ /* also prettify the first segment */
410
+ z += strlen(mark);
411
+ z[0] = fossil_toupper(z[0]);
412
+ for(; z[0]!=0; z++ ){
413
+ if( z[0]=='_' ) z[0] = ' ';
414
+ else if( z[0] == '/' ){ /* show just the first segment */
415
+ z[0] = 0;
416
+ break;
417
+ }
418
+ }
419
+ }
420
+ if( zQS[0] ){
421
+ aSubmenu[nSubmenu].zLink = mprintf("%R/%s?%s",zV,zQS);
422
+ }else{
423
+ aSubmenu[nSubmenu].zLink = mprintf("%R/%s",zV);
424
+ }
425
+ nSubmenu++;
426
+ }
427
+ }
428
+}
334429
335430
/*
336431
** Disable or enable the submenu
337432
*/
338433
void style_submenu_enable(int onOff){
@@ -907,11 +1002,11 @@
9071002
qsort(aSubmenu, nSubmenu, sizeof(aSubmenu[0]), submenuCompare);
9081003
for(i=0; i<nSubmenu; i++){
9091004
struct Submenu *p = &aSubmenu[i];
9101005
/* switching away from the %h formatting below might be dangerous
9111006
** because some places use %s to compose zLabel and zLink;
912
- ** e.g. /rptview page
1007
+ ** e.g. /rptview page and the style_submenu_parametic() function
9131008
*/
9141009
if( p->zLink==0 ){
9151010
@ <span class="label">%h(p->zLabel)</span>
9161011
}else{
9171012
@ <a class="label" href="%h(p->zLink)">%h(p->zLabel)</a>
9181013
--- src/style.c
+++ src/style.c
@@ -32,10 +32,11 @@
32 ** style_submenu_entry()
33 ** style_submenu_checkbox()
34 ** style_submenu_binary()
35 ** style_submenu_multichoice()
36 ** style_submenu_sql()
 
37 **
38 ** prior to calling style_finish_page(). The style_finish_page() routine
39 ** will generate the appropriate HTML text just below the main
40 ** menu.
41 */
@@ -329,10 +330,104 @@
329 aSubmenuCtrl[nSubmenuCtrl].eVisible = STYLE_NORMAL;
330 aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI;
331 nSubmenuCtrl++;
332 }
333 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
335 /*
336 ** Disable or enable the submenu
337 */
338 void style_submenu_enable(int onOff){
@@ -907,11 +1002,11 @@
907 qsort(aSubmenu, nSubmenu, sizeof(aSubmenu[0]), submenuCompare);
908 for(i=0; i<nSubmenu; i++){
909 struct Submenu *p = &aSubmenu[i];
910 /* switching away from the %h formatting below might be dangerous
911 ** because some places use %s to compose zLabel and zLink;
912 ** e.g. /rptview page
913 */
914 if( p->zLink==0 ){
915 @ <span class="label">%h(p->zLabel)</span>
916 }else{
917 @ <a class="label" href="%h(p->zLink)">%h(p->zLabel)</a>
918
--- src/style.c
+++ src/style.c
@@ -32,10 +32,11 @@
32 ** style_submenu_entry()
33 ** style_submenu_checkbox()
34 ** style_submenu_binary()
35 ** style_submenu_multichoice()
36 ** style_submenu_sql()
37 ** style_submenu_parametric()
38 **
39 ** prior to calling style_finish_page(). The style_finish_page() routine
40 ** will generate the appropriate HTML text just below the main
41 ** menu.
42 */
@@ -329,10 +330,104 @@
330 aSubmenuCtrl[nSubmenuCtrl].eVisible = STYLE_NORMAL;
331 aSubmenuCtrl[nSubmenuCtrl].eType = FF_MULTI;
332 nSubmenuCtrl++;
333 }
334 }
335
336 /* Add hyperlinks depending on the existence and values of special
337 ** parameters in the request's query string. The names of a query's
338 ** parameters that are investigated are obtainted by concatenation of
339 ** the caller-provided zPrefix with suffix "smplXY", where optional
340 ** ending XY consists of a digit X from the set {1,2,3,4,5} and an
341 ** optional letter Y which (if present) must be either 'a' or 's'.
342 ** zPrefix must start with a lowercase letter,
343 ** be short and have no strange characters. Parameter's value
344 ** is well-formed if its first filepath segment (separated by '/')
345 ** has no strange characters. Malformed values are silently ignored.
346 **
347 ** The text for the resulting submenu label equals to the value of the
348 ** parameter modulus some prettification for better UX:
349 ** 1) If a parameter's value starts with a lowercase letter and
350 ** contains '/' then it goes unchanged into the user-visible label.
351 ** 2a) If the first letter is uppercase then the label is
352 ** truncated at the first '/' (if any),
353 ** 2b) otherwise the first letter is capitalized.
354 ** 3) Underscores in the first path segment are replaced with spaces.
355 ** 4) If the resulting label starts with an uppercase letter
356 ** then it is prepended with "✧" symbol for explicit distinction
357 ** from the built-in labels
358 **
359 ** Important security-related note:
360 ** zLabel and zLink are formatted using %s because it is expected that
361 ** style_finish_page() provides propper escaping via %h format.
362 */
363 void style_submenu_parametric(
364 const char *zPrefix /* common prefix of the query parameters names */
365 ){
366 static const char *suffix = "smpl"; /* common suffix for param names */
367 static const short sfxlen = 4; /* length of the above suffix */
368 static const char sfxext[3] = {'a','s',0}; /* extra suffix ending */
369 const char *zQS; /* QUERY_STRING */
370 char zN[32]; /* buffer for parameter names to probe */
371 short i,j,l;
372
373 /* zPrefix must be tidy and short; also filter out ENV/CGI variables */
374 assert( zPrefix != 0 && fossil_islower(zPrefix[0]) );
375 l = strnlen( zPrefix, sizeof(zN) );
376 assert( l+sfxlen+3 <= sizeof(zN) );
377 assert( fossil_no_strange_characters(zPrefix) );
378 /* concatenate zPrefix and suffix */
379 strcpy( zN, zPrefix );
380 strcpy( zN + l, suffix );
381 l += sfxlen;
382 zN[l+2] = 0; /* nul-terminator after ...smplXY suffix */
383 zQS = PD("QUERY_STRING","");
384 for( i = 0; i <= 5; i++ ){
385 zN[l] = ( i == 0 ? 0 : '0' + i ); /* ...smpl instead of ...smpl0 */
386 for( j = (i ? 0 : sizeof(sfxext)-1); j < sizeof(sfxext); j++ ){
387 const char *zV, *z;
388 zN[l+1] = sfxext[j];
389 zV = PD(zN,"");
390 if( zV[0] == 0 || zV[0] == '/' || zV[0] == '_' || zV[0] == '-' ){
391 continue;
392 }
393 /* require the first path segment to be unfancy ASCII string */
394 for( z = zV; z[0] && z[0] != '/' ;){
395 if( fossil_isalnum(z[0]) || z[0]=='_' || z[0]=='-' ) z++;
396 else break;
397 }
398 if( z[0] != 0 && z[0] != '/' )
399 continue;
400 assert( nSubmenu < count(aSubmenu) );
401 if(fossil_islower(zV[0]) && z[0]=='/'){
402 aSubmenu[nSubmenu].zLabel = mprintf( "%s",zV); /* memory leak? */
403 }else{
404 /* prepend a label with an unobtrusive symbol that "sorts-last";
405 ** this clearly distincts it from the built-in elements */
406 static const char *mark = "✧";
407 char *z = mprintf("%s%s",mark,zV);
408 aSubmenu[nSubmenu].zLabel = z;
409 /* also prettify the first segment */
410 z += strlen(mark);
411 z[0] = fossil_toupper(z[0]);
412 for(; z[0]!=0; z++ ){
413 if( z[0]=='_' ) z[0] = ' ';
414 else if( z[0] == '/' ){ /* show just the first segment */
415 z[0] = 0;
416 break;
417 }
418 }
419 }
420 if( zQS[0] ){
421 aSubmenu[nSubmenu].zLink = mprintf("%R/%s?%s",zV,zQS);
422 }else{
423 aSubmenu[nSubmenu].zLink = mprintf("%R/%s",zV);
424 }
425 nSubmenu++;
426 }
427 }
428 }
429
430 /*
431 ** Disable or enable the submenu
432 */
433 void style_submenu_enable(int onOff){
@@ -907,11 +1002,11 @@
1002 qsort(aSubmenu, nSubmenu, sizeof(aSubmenu[0]), submenuCompare);
1003 for(i=0; i<nSubmenu; i++){
1004 struct Submenu *p = &aSubmenu[i];
1005 /* switching away from the %h formatting below might be dangerous
1006 ** because some places use %s to compose zLabel and zLink;
1007 ** e.g. /rptview page and the style_submenu_parametic() function
1008 */
1009 if( p->zLink==0 ){
1010 @ <span class="label">%h(p->zLabel)</span>
1011 }else{
1012 @ <a class="label" href="%h(p->zLink)">%h(p->zLabel)</a>
1013
+1
--- src/wiki.c
+++ src/wiki.c
@@ -593,10 +593,11 @@
593593
}else if( rid && g.perm.ApndWiki ){
594594
style_submenu_element("Edit", "%R/wikiappend?name=%T", zPageName);
595595
}
596596
if( g.perm.Hyperlink ){
597597
style_submenu_element("History", "%R/whistory?name=%T", zPageName);
598
+ style_submenu_parametric("wiki");
598599
}
599600
}
600601
if( !isPopup ){
601602
style_set_current_page("%T?name=%T", g.zPath, zPageName);
602603
wiki_page_header(WIKITYPE_UNKNOWN, zPageName, "");
603604
--- src/wiki.c
+++ src/wiki.c
@@ -593,10 +593,11 @@
593 }else if( rid && g.perm.ApndWiki ){
594 style_submenu_element("Edit", "%R/wikiappend?name=%T", zPageName);
595 }
596 if( g.perm.Hyperlink ){
597 style_submenu_element("History", "%R/whistory?name=%T", zPageName);
 
598 }
599 }
600 if( !isPopup ){
601 style_set_current_page("%T?name=%T", g.zPath, zPageName);
602 wiki_page_header(WIKITYPE_UNKNOWN, zPageName, "");
603
--- src/wiki.c
+++ src/wiki.c
@@ -593,10 +593,11 @@
593 }else if( rid && g.perm.ApndWiki ){
594 style_submenu_element("Edit", "%R/wikiappend?name=%T", zPageName);
595 }
596 if( g.perm.Hyperlink ){
597 style_submenu_element("History", "%R/whistory?name=%T", zPageName);
598 style_submenu_parametric("wiki");
599 }
600 }
601 if( !isPopup ){
602 style_set_current_page("%T?name=%T", g.zPath, zPageName);
603 wiki_page_header(WIKITYPE_UNKNOWN, zPageName, "");
604
--- www/changes.wiki
+++ www/changes.wiki
@@ -20,12 +20,15 @@
2020
The [/help?cmd=tag|tag command] can now manipulate and list such tags.
2121
* [./caps/login-groups.md|Login-Groups] are now show on the repository
2222
list of the "[/help?cmd=all|fossil all ui]" command.
2323
* Administrators can configure [./alerts|email alerts] to expire
2424
a specific number of days (ex: 365) after the last user contact with
25
- the Fossil server
2625
This can prevents alert emails being sent to
26
+ the Fossil server. This prevents alert emails being sent to
2727
abandoned email accounts forever.
28
+ * Submenu of the [/help?cmd=/rptview|/rptview] and
29
+ [/help?cmd=/wiki|/wiki] pages may be
30
+ [branch/rptview-submenu-paralink|extended with auxiliary hyperlinks].
2831
2932
<a name='v2_15'></a>
3033
<h2>Changes for Version 2.15 (2021-03-26) and Patch 2.15.1 on (2021-04-07)</h2>
3134
* <b>Patch 2.15.1:</b> Fix a data exfiltration bug in the server. <b>Upgrading to
3235
the patch is recommended.</b><p>
3336
--- www/changes.wiki
+++ www/changes.wiki
@@ -20,12 +20,15 @@
20 The [/help?cmd=tag|tag command] can now manipulate and list such tags.
21 * [./caps/login-groups.md|Login-Groups] are now show on the repository
22 list of the "[/help?cmd=all|fossil all ui]" command.
23 * Administrators can configure [./alerts|email alerts] to expire
24 a specific number of days (ex: 365) after the last user contact with
25 the Fossil server
26 This can prevents alert emails being sent to
 
27 abandoned email accounts forever.
 
 
 
28
29 <a name='v2_15'></a>
30 <h2>Changes for Version 2.15 (2021-03-26) and Patch 2.15.1 on (2021-04-07)</h2>
31 * <b>Patch 2.15.1:</b> Fix a data exfiltration bug in the server. <b>Upgrading to
32 the patch is recommended.</b><p>
33
--- www/changes.wiki
+++ www/changes.wiki
@@ -20,12 +20,15 @@
20 The [/help?cmd=tag|tag command] can now manipulate and list such tags.
21 * [./caps/login-groups.md|Login-Groups] are now show on the repository
22 list of the "[/help?cmd=all|fossil all ui]" command.
23 * Administrators can configure [./alerts|email alerts] to expire
24 a specific number of days (ex: 365) after the last user contact with
 
25 This can prevents alert emails being sent to
26 the Fossil server. This prevents alert emails being sent to
27 abandoned email accounts forever.
28 * Submenu of the [/help?cmd=/rptview|/rptview] and
29 [/help?cmd=/wiki|/wiki] pages may be
30 [branch/rptview-submenu-paralink|extended with auxiliary hyperlinks].
31
32 <a name='v2_15'></a>
33 <h2>Changes for Version 2.15 (2021-03-26) and Patch 2.15.1 on (2021-04-07)</h2>
34 * <b>Patch 2.15.1:</b> Fix a data exfiltration bug in the server. <b>Upgrading to
35 the patch is recommended.</b><p>
36
--- www/changes.wiki
+++ www/changes.wiki
@@ -20,12 +20,15 @@
2020
The [/help?cmd=tag|tag command] can now manipulate and list such tags.
2121
* [./caps/login-groups.md|Login-Groups] are now show on the repository
2222
list of the "[/help?cmd=all|fossil all ui]" command.
2323
* Administrators can configure [./alerts|email alerts] to expire
2424
a specific number of days (ex: 365) after the last user contact with
25
- the Fossil server
2625
This can prevents alert emails being sent to
26
+ the Fossil server. This prevents alert emails being sent to
2727
abandoned email accounts forever.
28
+ * Submenu of the [/help?cmd=/rptview|/rptview] and
29
+ [/help?cmd=/wiki|/wiki] pages may be
30
+ [branch/rptview-submenu-paralink|extended with auxiliary hyperlinks].
2831
2932
<a name='v2_15'></a>
3033
<h2>Changes for Version 2.15 (2021-03-26) and Patch 2.15.1 on (2021-04-07)</h2>
3134
* <b>Patch 2.15.1:</b> Fix a data exfiltration bug in the server. <b>Upgrading to
3235
the patch is recommended.</b><p>
3336
--- www/changes.wiki
+++ www/changes.wiki
@@ -20,12 +20,15 @@
20 The [/help?cmd=tag|tag command] can now manipulate and list such tags.
21 * [./caps/login-groups.md|Login-Groups] are now show on the repository
22 list of the "[/help?cmd=all|fossil all ui]" command.
23 * Administrators can configure [./alerts|email alerts] to expire
24 a specific number of days (ex: 365) after the last user contact with
25 the Fossil server
26 This can prevents alert emails being sent to
 
27 abandoned email accounts forever.
 
 
 
28
29 <a name='v2_15'></a>
30 <h2>Changes for Version 2.15 (2021-03-26) and Patch 2.15.1 on (2021-04-07)</h2>
31 * <b>Patch 2.15.1:</b> Fix a data exfiltration bug in the server. <b>Upgrading to
32 the patch is recommended.</b><p>
33
--- www/changes.wiki
+++ www/changes.wiki
@@ -20,12 +20,15 @@
20 The [/help?cmd=tag|tag command] can now manipulate and list such tags.
21 * [./caps/login-groups.md|Login-Groups] are now show on the repository
22 list of the "[/help?cmd=all|fossil all ui]" command.
23 * Administrators can configure [./alerts|email alerts] to expire
24 a specific number of days (ex: 365) after the last user contact with
 
25 This can prevents alert emails being sent to
26 the Fossil server. This prevents alert emails being sent to
27 abandoned email accounts forever.
28 * Submenu of the [/help?cmd=/rptview|/rptview] and
29 [/help?cmd=/wiki|/wiki] pages may be
30 [branch/rptview-submenu-paralink|extended with auxiliary hyperlinks].
31
32 <a name='v2_15'></a>
33 <h2>Changes for Version 2.15 (2021-03-26) and Patch 2.15.1 on (2021-04-07)</h2>
34 * <b>Patch 2.15.1:</b> Fix a data exfiltration bug in the server. <b>Upgrading to
35 the patch is recommended.</b><p>
36

Keyboard Shortcuts

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