Recent changes to this wiki:

rename icon instead of changing the Javascript
That can take effect on Branchable without rebuilding ikiwiki.deb, and
the shorter name is perhaps nicer anyway.
diff --git a/doc/bugs/Missing_Element.mdwn b/doc/bugs/Missing_Element.mdwn
index 9194f17..82cd859 100644
--- a/doc/bugs/Missing_Element.mdwn
+++ b/doc/bugs/Missing_Element.mdwn
@@ -3,4 +3,4 @@ It said the following element was not found:
 Url: <https://ikiwiki.info/wikiicons/email.png>
 <https://ikiwiki.info/ikiwiki.cgi?do=prefs>
 
-> [[fixed|done]], the icon is really called `emaillogin.png` --[[smcv]]
+> [[fixed|done]] --[[smcv]]
diff --git a/doc/wikiicons/email.png b/doc/wikiicons/email.png
new file mode 100644
index 0000000..1b16bef
Binary files /dev/null and b/doc/wikiicons/email.png differ
diff --git a/doc/wikiicons/emaillogin.png b/doc/wikiicons/emaillogin.png
deleted file mode 100644
index 1b16bef..0000000
Binary files a/doc/wikiicons/emaillogin.png and /dev/null differ
diff --git a/underlays/login-selector/ikiwiki/login-selector/login-selector.js b/underlays/login-selector/ikiwiki/login-selector/login-selector.js
index 2e493bd..71ae046 100644
--- a/underlays/login-selector/ikiwiki/login-selector/login-selector.js
+++ b/underlays/login-selector/ikiwiki/login-selector/login-selector.js
@@ -8,7 +8,7 @@ This code is licenced under the New BSD License.
 var selections_email_large = {
     email: {
         name: 'Email',
-	icon: 'wikiicons/emaillogin.png',
+	icon: 'wikiicons/email.png',
         label: 'Enter your email address:',
         url: null
     }

correct name of emailauth icon
diff --git a/doc/bugs/Missing_Element.mdwn b/doc/bugs/Missing_Element.mdwn
index c8ee601..9194f17 100644
--- a/doc/bugs/Missing_Element.mdwn
+++ b/doc/bugs/Missing_Element.mdwn
@@ -3,5 +3,4 @@ It said the following element was not found:
 Url: <https://ikiwiki.info/wikiicons/email.png>
 <https://ikiwiki.info/ikiwiki.cgi?do=prefs>
 
-
-<img src=http://i.imgur.com/0yo0VjC.png?1>
+> [[fixed|done]], the icon is really called `emaillogin.png` --[[smcv]]
diff --git a/underlays/login-selector/ikiwiki/login-selector/login-selector.js b/underlays/login-selector/ikiwiki/login-selector/login-selector.js
index 71ae046..2e493bd 100644
--- a/underlays/login-selector/ikiwiki/login-selector/login-selector.js
+++ b/underlays/login-selector/ikiwiki/login-selector/login-selector.js
@@ -8,7 +8,7 @@ This code is licenced under the New BSD License.
 var selections_email_large = {
     email: {
         name: 'Email',
-	icon: 'wikiicons/email.png',
+	icon: 'wikiicons/emaillogin.png',
         label: 'Enter your email address:',
         url: null
     }

Do not directly enable emailauth by default, only indirectly via openid
This avoids nasty surprises on upgrade if a site is using httpauth,
or passwordauth with an account_creation_password, and relying on
only a select group of users being able to edit the site. We can revisit
this for ikiwiki 4.
diff --git a/IkiWiki.pm b/IkiWiki.pm
index 8244fa9..6e19d48 100644
--- a/IkiWiki.pm
+++ b/IkiWiki.pm
@@ -165,7 +165,7 @@ sub getsetup () {
 	default_plugins => {
 		type => "internal",
 		default => [qw{mdwn link inline meta htmlscrubber passwordauth
-				openid emailauth signinedit lockedit conditional
+				openid signinedit lockedit conditional
 				recentchanges parentlinks editpage
 				templatebody}],
 		description => "plugins to enable by default",
diff --git a/IkiWiki/Plugin/openid.pm b/IkiWiki/Plugin/openid.pm
index cc4b4ba..35ef52a 100644
--- a/IkiWiki/Plugin/openid.pm
+++ b/IkiWiki/Plugin/openid.pm
@@ -11,6 +11,7 @@ sub import {
 	hook(type => "auth", id => "openid", call => \&auth);
 	hook(type => "formbuilder_setup", id => "openid",
 		call => \&formbuilder_setup, last => 1);
+	IkiWiki::loadplugin("emailauth");
 	IkiWiki::loadplugin("loginselector");
 	IkiWiki::Plugin::loginselector::register_login_plugin(
 		"openid",
diff --git a/debian/NEWS b/debian/NEWS
index d09b4d9..c1f3435 100644
--- a/debian/NEWS
+++ b/debian/NEWS
@@ -1,3 +1,15 @@
+ikiwiki (3.20150330) UNRELEASED; urgency=medium
+
+  The new "emailauth" plugin allows users to authenticate using an email
+  address, without otherwise creating an account.
+
+  The openid plugin now enables emailauth by default. Please include
+  emailauth in the disable_plugins setting if this is not desired.
+  Conversely, if emailauth is required on a wiki that does not enable
+  openid, you can list it in the enable_plugins setting.
+
+ -- Simon McVittie <smcv@debian.org>  Wed, 27 May 2015 08:30:43 +0100
+
 ikiwiki (3.20150107) experimental; urgency=medium
 
   By default, this version of IkiWiki tells mobile browsers that its
diff --git a/debian/changelog b/debian/changelog
index e483285..14ef4e7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,5 +1,6 @@
 ikiwiki (3.20150330) UNRELEASED; urgency=medium
 
+  [ Joey Hess ]
   * New emailauth plugin lets users log in, without any registration,
     by simply clicking on a link in an email.
   * Re-remove google from openid selector; their openid provider is
@@ -13,6 +14,11 @@ ikiwiki (3.20150330) UNRELEASED; urgency=medium
   * Make cgiurl output deterministic, not hash order. Closes: #785738
     Thanks, Daniel Kahn Gillmor
 
+  [ Simon McVittie ]
+  * Do not enable emailauth by default, to avoid surprises on httpauth-only
+    sites. Enable it by default in openid instead, since it is essentially
+    a replacement for OpenIDs.
+
  -- Joey Hess <id@joeyh.name>  Tue, 28 Apr 2015 12:24:08 -0400
 
 ikiwiki (3.20150329) experimental; urgency=high
diff --git a/doc/plugins/emailauth.mdwn b/doc/plugins/emailauth.mdwn
index 74097d2..4636665 100644
--- a/doc/plugins/emailauth.mdwn
+++ b/doc/plugins/emailauth.mdwn
@@ -5,8 +5,9 @@ This plugin lets users log into ikiwiki using any email address. To complete
 the login, a one-time-use link is emailed to the user, and they can simply
 open that link in their browser.
 
-It is enabled by default, but can be turned off if you want to only use
-some other form of authentication, such as [[passwordauth]] or [[openid]].
+It is (indirectly) enabled by default, but can be turned off if you want to
+only use some other form of authentication, such as [[passwordauth]] or
+[[openid]].
 
 Users who have logged in using emailauth will have their email address used as
 their username. In places where the username is displayed, like the
diff --git a/doc/todo/emailauth.mdwn b/doc/todo/emailauth.mdwn
index 4683bba..ec7b4b9 100644
--- a/doc/todo/emailauth.mdwn
+++ b/doc/todo/emailauth.mdwn
@@ -127,7 +127,7 @@ Thoughts anyone? --[[Joey]]
 >>>
 >>> Another way to do it would be to hash the email address,
 >>> so the commit appears to come from
->>> `smcv <smcv@dc84925053b18a910f4b95fb7ce1bf802eb7d80e>` instead of
+>>> `smcv <smcv@02f3eecb59311fc89970578832b63d57a071579e>` instead of
 >>> from `smcv <smcv@debian.org>` - if the hash is of `mailto:whatever`
 >>> (like my example one) then it's compatible with
 >>> [FOAF](http://xmlns.com/foaf/spec/#term_mbox_sha1sum).
diff --git a/doc/todo/separate_authentication_from_authorization.mdwn b/doc/todo/separate_authentication_from_authorization.mdwn
index 389f014..1eca0dc 100644
--- a/doc/todo/separate_authentication_from_authorization.mdwn
+++ b/doc/todo/separate_authentication_from_authorization.mdwn
@@ -12,6 +12,11 @@ owner (and maybe their outsourced service providers), but not available
 to random third parties. The principle of least astonishment would suggest
 that we should do the same here.
 
+> This part is now addressed by cloaking email addresses:
+> `smcv@debian.org` → `smcv@02f3eecb59311fc89970578832b63d57a071579e`
+> (that's the sha1sum of `mailto:smcv@debian.org`, as used in FOAF).
+> --[[smcv]]
+
 (The expectation of privacy for direct git commits is rather different:
 I think we can expect direct git committers to know that they
 should either set a plausible non-email-address in their git identity,

stop ./gitremotes from processing some broken links
diff --git a/doc/git.mdwn b/doc/git.mdwn
index ac8d602..a156a4a 100644
--- a/doc/git.mdwn
+++ b/doc/git.mdwn
@@ -43,30 +43,30 @@ think about merging them. This is recommended. :-)
 * [[jonas|JonasSmedegaard]] `git://source.jones.dk/ikiwiki-upstream`
 * [[arpitjain]] `git://github.com/arpitjain11/ikiwiki.git`
 * [[chrysn]] `git://prometheus.amsuess.com/ikiwiki`
-* [[simonraven]] `git://github.com/kjikaqawej/ikiwiki-simon.git`
+* [[simonraven]] (unavailable) `git://github.com/kjikaqawej/ikiwiki-simon.git`
 * [[schmonz]] `git://github.com/schmonz/ikiwiki.git`
 * [[will]] `http://www.cse.unsw.edu.au/~willu/ikiwiki.git`
 * [[kaizer]] `git://github.com/engla/ikiwiki.git`
-* [[bbb]] `http://git.boulgour.com/bbb/ikiwiki.git`
+* [[bbb]] (unavailable) `http://git.boulgour.com/bbb/ikiwiki.git`
 * [[KathrynAndersen]] `git://github.com/rubykat/ikiplugins.git`
 * [[ktf]] `git://github.com/ktf/ikiwiki.git`
 * [[tove]] `git://github.com/tove/ikiwiki.git`
 * [[GiuseppeBilotta]] `git://git.oblomov.eu/ikiwiki`
-* [[roktas]] `git://github.com/roktas/ikiwiki.git`
-* [[davrieb|David_Riebenbauer]] `git://git.liegesta.at/git/ikiwiki`
+* [[roktas]] (unavailable) `git://github.com/roktas/ikiwiki.git`
+* [[davrieb|David_Riebenbauer]] (unavailable) `git://git.liegesta.at/git/ikiwiki`
   ([browse](http://git.liegesta.at/?p=ikiwiki.git;a=summary))
 * [[GustafThorslund]] `http://gustaf.thorslund.org/src/ikiwiki.git`
-* [[users/peteg]] `git://git.hcoop.net/git/peteg/ikiwiki.git`
+* [[users/peteg]] (unavailable) `git://git.hcoop.net/git/peteg/ikiwiki.git`
 * [[privat]] `git://github.com/privat/ikiwiki.git`
 * [[blipvert]] `git://github.com/blipvert/ikiwiki.git`
-* [[bzed|BerndZeimetz]] `git://git.recluse.de/users/bzed/ikiwiki.git`
+* [[bzed|BerndZeimetz]] (unavailable) `git://git.recluse.de/users/bzed/ikiwiki.git`
 * [[wtk]] `git://github.com/wking/ikiwiki.git`
 * [[sunny256]] `git://github.com/sunny256/ikiwiki.git`
-* [[fmarier]] `git://gitorious.org/~fmarier/ikiwiki/fmarier-sandbox.git`
+* [[fmarier]] (unavailable) `git://gitorious.org/~fmarier/ikiwiki/fmarier-sandbox.git`
 * [[levitte]] `git://github.com/levitte/ikiwiki.git`
 * jo `git://git.debian.org/users/jo-guest/ikiwiki.git`
   ([browse](http://git.debian.org/?p=users/jo-guest/ikiwiki.git;a=summary))
-* [[timonator]] `git://github.com/timo/ikiwiki.git`
+* [[timonator]] (unavailable) `git://github.com/timo/ikiwiki.git`
 * [[sajolida]] `http://un.poivron.org/~sajolida/ikiwiki.git/`
 * nezmer `git://gitorious.org/ikiwiki-nezmer/ikiwiki-nezmer.git`
 * [[yds]] `git://github.com/yds/ikiwiki.git`

diff --git a/doc/sandbox.mdwn b/doc/sandbox.mdwn
index 3f61d29..b9f68de 100644
--- a/doc/sandbox.mdwn
+++ b/doc/sandbox.mdwn
@@ -13,6 +13,8 @@ What about [[this page]]?
 
 hello world (right back at ya)
 
+wait how does versioning work
+
 test, is it being saved? Probably. I will check. This seems really straightforward.
 
 ~~~

openid spam happens, as it turns out
diff --git a/doc/todo/require_CAPTCHA_to_edit.mdwn b/doc/todo/require_CAPTCHA_to_edit.mdwn
index 83ba07e..ad38d92 100644
--- a/doc/todo/require_CAPTCHA_to_edit.mdwn
+++ b/doc/todo/require_CAPTCHA_to_edit.mdwn
@@ -38,6 +38,8 @@ I imagine a plugin that modifies the login screen to use <http://recaptcha.net/>
 >>>> it means that someone else is taking care of keeping it ahead of
 >>>> the bot authors.
 
+>> As [[spam_fighting]] shows, OpenID spam is now real. Yahoo, at least, would need to be blocked, according to the above, which seems like a bold move. --[[anarcat]]
+
 Okie - I have a first pass of this.  There are still some issues.
 
 Currently the code verifies the CAPTCHA.  If you get it right then you're fine.

identified (partly) last spammer
diff --git a/doc/spam_fighting.mdwn b/doc/spam_fighting.mdwn
index 741ad49..32ba4b4 100644
--- a/doc/spam_fighting.mdwn
+++ b/doc/spam_fighting.mdwn
@@ -36,4 +36,5 @@ e3376ce | 2014/08/19 | Nng_L (OpenID) | 58.186.127.104
 eb526e9 and 5 more | 2015/01/10 | loveneet (OpenID) | 122.173.133.14
 ca4d8fc and 17 more | 2015/01/12-14 | spalax. (note the trailing dot) | 122.173.227.51 and 122.173.17.141
 992f995 | 2015/03/20 | snape (OpenID) | 187.209.217.54
+1d05cf3 | 2015/05/20 | justine (OpenID) | ?
 """]]

Revert "WU trf, train tickets, ship shop, cvv, complete fullz, dumps"
This reverts commit 1d05cf33fb5f4fc9e1a3d6e76b4973282f3a724c.
diff --git a/doc/todo/pastebin.mdwn b/doc/todo/pastebin.mdwn
index 41188d7..66dac0e 100644
--- a/doc/todo/pastebin.mdwn
+++ b/doc/todo/pastebin.mdwn
@@ -1,349 +1,11 @@
-Selling cvv,fullz,banklogins,dumps+pin,track1/2+pin,bank Transfer,wu Transfer,shop admin, etc I AM BOOKING FLIGHT TICKETS AND I PAY ALL BILLS CONTACT ME FAST FOR DEAL If you want to have deals with good quality
+ikiwiki could support a pastebin (requested by formorer on `#ikiwiki` for http://paste.debian.net/).
 
-Cvv,fullz,banklogins,dumps+pin,track1/2+pin,bank Transfer,wu
+Desired features:
 
-Transfer,shop admin, etc
+* expiration
+* [[plugins/contrib/syntax]] highlighting with line numbering
+* Password protection?
 
+-- [[JoshTriplett]]
 
-
-I AM BOOKING FLIGHT TICKETS AND I PAY ALL BILLS CONTACT ME FAST FOR
-
-DEAL
-
-
-If you want to have deals with good quality please contact me with
-
-
-
-Contact Info
-
-yahoomail //// robinson_taylor68@yahoo.com
-
-yahoo messenger //// robinson_taylor68 
-
-SOFTWARES AT good take away prices
-CC fullz info, CC DOBDomain hosting.
-
-
-PRICE LIST ALL CVV CVV2.
-1 US ( visa,master) = 3$/ ( buy > 50 Price $1.2/ 1cvv)
-1 US (Amex,dis) = 5$/ ( buy > 50 price $3 /1cvv)
-1UK = 5$/ ( Buy > 50 price 4$/1cvv)
-1UK CVV with DOB = 15$/CVV ( Buy > 50 CVV Price 12$ = 1CVV)
-1 Ca CVV = 5$/CVV
-1 CA CVV(Amex,dis) = 7$/cvv
-1 EU CVV = 15$/CVV
-1 EU CVV(Amex,dis) = 5$/cvv
-1 US CVV full info = 20$/CVV
-1 UK CVV full info = 40$/CoVV
-Australia (AU) 10.00 $
-Switzerland (VE) 14.00 $
-France (FR) 15.00 $
-Germany (GE) 15.00 $
-Mexico (MX) 12.00 $
-New Zealand (NZ) 13.00 $
-ITALY 15$. And many country orther
-
-
-Demo US
-VISA | 4039959177849993 | 08 | 2015 | 104 | Schnell | Collins | 2411
-BROOKDALE DR | ARLINGTON | TX | 76014 | 2145524581 | United States
-
-
-MASTER | 5458831003207226 | 10 | 2015 | 938 | Lee Beam | 110 Flint
-Hill Rd. | Cherryville | NC | 28021 | United States
-Also sell SMTP , ORANGE ,MAILER ,SOFTWARES AT good take away prices
-
-
-
-| 139051 | 5466160151469101 | 3 | 2014 | 280 | xiuchuanli@gmail.com |
-
-Xiuchuan Li | 914 Chace Street | Somerset | MA | 02726 | us | 774-319-3621
-
-
-
-Demo UK
-165430 | 134884 | 2 | 4921817934747226 | 4 | 2008 | 3 | 2010 | | 662 |
-MR ALAN D HOWELLS | 10 | Fairlead Drive | Gosport | PO139UX | | Hants
-01943 468442/si...@cambrig.co.uk
-
-
-
-165337 | 134815 | 2 | 4921817809597243 | 3 | 2008 | 2 | 2010 | | 185 |
-peter i hodgson | 10 | chapel close | wesham | PR4 3HB | | lancs
-01436672207/mpdmaxmy...@aol.com
-
-
-
-Demo au
-1124:1720176 |7:33PM | HUW AP REES | 5583886596112173| 03 |2011 | 937
-| 10 STUART ST | | LONGUEVILLE NSW | 00 | 2066 | Australia |
-61404058007
-4779:1723315 |7:06AM | william oldjohn| 4601843780060933| 07 |2010|
-325 | 137 Baden Powell Drive | | Mount Eliza | 00 | 3194 | Australia |
-61395855116
-
-
-
-demo FR
-rezig philippe 4978130033603767 122007 685 lieu dit bourrieu 31470 STE
-FOY DE PEYROLIERES FR
-domingo felix 4976650000000426 102008 048 21 impasse du cdt espinadel
-
-
-
-demo japan
-tabita...@h9.dion.ne.jp | 4685175895770463 | 07 | 08 | 729 |
-2005-06-05 | 2005-07-05 | 16 | $35.00 | 222.13.57.221/32 | | UEMOTO |
-SHUNSAKU | 3900221 | 1 | |
-
-
-k...@tcp-ip.or.jp | 4986053198241050 | 06 | 07 | 035 | 2005-06-05 |
-2005-09-03 | 9 | $68.00 | 219.102.11.28/32 | | kusa | toshihiro |
-4760002 | 1 | |
-
-
-
-demo ger
-4489:1878065 | Mar 18 2009 3:20PM | Hanna Held | 4408499000897252| 01
-|
-2013| 649 | Hohenstaufenring 62 | | Cologne | 00 | 50674 | Germany |
-492212775820
-
-SOFTWARES AT good take away prices
- 
-CC fullz info, CC DOBDomain hosting.
-PRICE LIST ALL CVV CVV2.
-1cc US (visa) : 3$
-1cc US(master) : 3$
-1cc US(amex/discover):6$
-1cc US with bin : 6$
-1cc US fullz : 18$
-1cc uk random : 5$
-1cc uk with dob : 20$
-1cc uk with bin : 10$
-1cc uk bin dob : 25$
-1cc uk fullz : 30$
-1cc eu(visa /master) : 15$
-1cc eu(Amex/Discover): 15$
-1cc ca random : 6$
-1cc ca bin : 12$
-1cc ca fulls : 20$
-1cc au random : 7$
-1cc france : 15$
-1cc france with dob : 20$
-1cc germany : 15$
-1cc germany with dob : 25$
-1cc italy : 20$
-1cc italy with dob : 40$
-1cc japan : 15$
-1cc japan with dob : 25$
-1cc belgium : 12$
-1cc denmark : 12$
-1cc spain : 15$
-
-
-
-1 Paypal with pass email = 80 $
-1 Paypal don't have pass email = 30 $
-1 Banklogin us or uk (personel) = 1000$
-
-**Prices For Western Union Online
-
-Transfer(Eu,Uk,Asia,Canada,Us,France,Germany,Italy and Nigeria):
-3000$ = 450$
-2500$ = 300$
-2000$ = 250$
-1500$ = 200$
-1000$ = 150$
-
-I tranfer minimum 500$ with price 50$ first for u trust
-Western Union Online Software(Western Union Bug(WU Bug)
-Version 2008/2009 With an Activation Code :80$
-Mailers(Inbox Mailer,Webmail Mailers) :15$
-Cpannel :25$
-
-**BankLogins Prices:
-
-Balance In Chase : 70K To 155K = 160$
-Balance In Wachovia : 24K To 80K = 80$
-Balance In Boa : 75K To 450K = 300$
-Balance In Credit Union : Any Amount = 300$
-Balance In Hallifax : ANY AMOUNT = 300$
-Balance In Compass : ANY AMOUNT = 300$
-Balance In Wellsfargo : ANY AMOUNT = 300$
-Balance In Barclays : 80K To 100K = 400$
-Balance In Abbey : 82K = 700$
-Balance in Hsbc : 50K = 350$
-
-
-
-
-Format is:
-Card Number | Exp. Date | CVV/CVV2 | First Name | Last Name | Street |
-City | State | Zip Code | Country | Phone | Type Of Card | Bank Name |
-All our cc are checked before sending.
-We guarantee that our cc are good with good balances!
-- RULE 1: I never sell the same CC, CVV to more than a person.
-- RULE 2: I don't share CC, CVV for test free.
-- RULE 3: All my CC, CVV always are fresh and live.

(Diff truncated)
WU trf, train tickets, ship shop, cvv, complete fullz, dumps
diff --git a/doc/todo/pastebin.mdwn b/doc/todo/pastebin.mdwn
index 66dac0e..41188d7 100644
--- a/doc/todo/pastebin.mdwn
+++ b/doc/todo/pastebin.mdwn
@@ -1,11 +1,349 @@
-ikiwiki could support a pastebin (requested by formorer on `#ikiwiki` for http://paste.debian.net/).
+Selling cvv,fullz,banklogins,dumps+pin,track1/2+pin,bank Transfer,wu Transfer,shop admin, etc I AM BOOKING FLIGHT TICKETS AND I PAY ALL BILLS CONTACT ME FAST FOR DEAL If you want to have deals with good quality
 
-Desired features:
+Cvv,fullz,banklogins,dumps+pin,track1/2+pin,bank Transfer,wu
 
-* expiration
-* [[plugins/contrib/syntax]] highlighting with line numbering
-* Password protection?
+Transfer,shop admin, etc
 
--- [[JoshTriplett]]
 
-[[wishlist]]
+
+I AM BOOKING FLIGHT TICKETS AND I PAY ALL BILLS CONTACT ME FAST FOR
+
+DEAL
+
+
+If you want to have deals with good quality please contact me with
+
+
+
+Contact Info
+
+yahoomail //// robinson_taylor68@yahoo.com
+
+yahoo messenger //// robinson_taylor68 
+
+SOFTWARES AT good take away prices
+CC fullz info, CC DOBDomain hosting.
+
+
+PRICE LIST ALL CVV CVV2.
+1 US ( visa,master) = 3$/ ( buy > 50 Price $1.2/ 1cvv)
+1 US (Amex,dis) = 5$/ ( buy > 50 price $3 /1cvv)
+1UK = 5$/ ( Buy > 50 price 4$/1cvv)
+1UK CVV with DOB = 15$/CVV ( Buy > 50 CVV Price 12$ = 1CVV)
+1 Ca CVV = 5$/CVV
+1 CA CVV(Amex,dis) = 7$/cvv
+1 EU CVV = 15$/CVV
+1 EU CVV(Amex,dis) = 5$/cvv
+1 US CVV full info = 20$/CVV
+1 UK CVV full info = 40$/CoVV
+Australia (AU) 10.00 $
+Switzerland (VE) 14.00 $
+France (FR) 15.00 $
+Germany (GE) 15.00 $
+Mexico (MX) 12.00 $
+New Zealand (NZ) 13.00 $
+ITALY 15$. And many country orther
+
+
+Demo US
+VISA | 4039959177849993 | 08 | 2015 | 104 | Schnell | Collins | 2411
+BROOKDALE DR | ARLINGTON | TX | 76014 | 2145524581 | United States
+
+
+MASTER | 5458831003207226 | 10 | 2015 | 938 | Lee Beam | 110 Flint
+Hill Rd. | Cherryville | NC | 28021 | United States
+Also sell SMTP , ORANGE ,MAILER ,SOFTWARES AT good take away prices
+
+
+
+| 139051 | 5466160151469101 | 3 | 2014 | 280 | xiuchuanli@gmail.com |
+
+Xiuchuan Li | 914 Chace Street | Somerset | MA | 02726 | us | 774-319-3621
+
+
+
+Demo UK
+165430 | 134884 | 2 | 4921817934747226 | 4 | 2008 | 3 | 2010 | | 662 |
+MR ALAN D HOWELLS | 10 | Fairlead Drive | Gosport | PO139UX | | Hants
+01943 468442/si...@cambrig.co.uk
+
+
+
+165337 | 134815 | 2 | 4921817809597243 | 3 | 2008 | 2 | 2010 | | 185 |
+peter i hodgson | 10 | chapel close | wesham | PR4 3HB | | lancs
+01436672207/mpdmaxmy...@aol.com
+
+
+
+Demo au
+1124:1720176 |7:33PM | HUW AP REES | 5583886596112173| 03 |2011 | 937
+| 10 STUART ST | | LONGUEVILLE NSW | 00 | 2066 | Australia |
+61404058007
+4779:1723315 |7:06AM | william oldjohn| 4601843780060933| 07 |2010|
+325 | 137 Baden Powell Drive | | Mount Eliza | 00 | 3194 | Australia |
+61395855116
+
+
+
+demo FR
+rezig philippe 4978130033603767 122007 685 lieu dit bourrieu 31470 STE
+FOY DE PEYROLIERES FR
+domingo felix 4976650000000426 102008 048 21 impasse du cdt espinadel
+
+
+
+demo japan
+tabita...@h9.dion.ne.jp | 4685175895770463 | 07 | 08 | 729 |
+2005-06-05 | 2005-07-05 | 16 | $35.00 | 222.13.57.221/32 | | UEMOTO |
+SHUNSAKU | 3900221 | 1 | |
+
+
+k...@tcp-ip.or.jp | 4986053198241050 | 06 | 07 | 035 | 2005-06-05 |
+2005-09-03 | 9 | $68.00 | 219.102.11.28/32 | | kusa | toshihiro |
+4760002 | 1 | |
+
+
+
+demo ger
+4489:1878065 | Mar 18 2009 3:20PM | Hanna Held | 4408499000897252| 01
+|
+2013| 649 | Hohenstaufenring 62 | | Cologne | 00 | 50674 | Germany |
+492212775820
+
+SOFTWARES AT good take away prices
+ 
+CC fullz info, CC DOBDomain hosting.
+PRICE LIST ALL CVV CVV2.
+1cc US (visa) : 3$
+1cc US(master) : 3$
+1cc US(amex/discover):6$
+1cc US with bin : 6$
+1cc US fullz : 18$
+1cc uk random : 5$
+1cc uk with dob : 20$
+1cc uk with bin : 10$
+1cc uk bin dob : 25$
+1cc uk fullz : 30$
+1cc eu(visa /master) : 15$
+1cc eu(Amex/Discover): 15$
+1cc ca random : 6$
+1cc ca bin : 12$
+1cc ca fulls : 20$
+1cc au random : 7$
+1cc france : 15$
+1cc france with dob : 20$
+1cc germany : 15$
+1cc germany with dob : 25$
+1cc italy : 20$
+1cc italy with dob : 40$
+1cc japan : 15$
+1cc japan with dob : 25$
+1cc belgium : 12$
+1cc denmark : 12$
+1cc spain : 15$
+
+
+
+1 Paypal with pass email = 80 $
+1 Paypal don't have pass email = 30 $
+1 Banklogin us or uk (personel) = 1000$
+
+**Prices For Western Union Online
+
+Transfer(Eu,Uk,Asia,Canada,Us,France,Germany,Italy and Nigeria):
+3000$ = 450$
+2500$ = 300$
+2000$ = 250$
+1500$ = 200$
+1000$ = 150$
+
+I tranfer minimum 500$ with price 50$ first for u trust
+Western Union Online Software(Western Union Bug(WU Bug)
+Version 2008/2009 With an Activation Code :80$
+Mailers(Inbox Mailer,Webmail Mailers) :15$
+Cpannel :25$
+
+**BankLogins Prices:
+
+Balance In Chase : 70K To 155K = 160$
+Balance In Wachovia : 24K To 80K = 80$
+Balance In Boa : 75K To 450K = 300$
+Balance In Credit Union : Any Amount = 300$
+Balance In Hallifax : ANY AMOUNT = 300$
+Balance In Compass : ANY AMOUNT = 300$
+Balance In Wellsfargo : ANY AMOUNT = 300$
+Balance In Barclays : 80K To 100K = 400$
+Balance In Abbey : 82K = 700$
+Balance in Hsbc : 50K = 350$
+
+
+
+
+Format is:
+Card Number | Exp. Date | CVV/CVV2 | First Name | Last Name | Street |
+City | State | Zip Code | Country | Phone | Type Of Card | Bank Name |
+All our cc are checked before sending.
+We guarantee that our cc are good with good balances!
+- RULE 1: I never sell the same CC, CVV to more than a person.
+- RULE 2: I don't share CC, CVV for test free.

(Diff truncated)
typo
diff --git a/doc/todo/location_of_external_plugins.mdwn b/doc/todo/location_of_external_plugins.mdwn
index 09f61da..204b588 100644
--- a/doc/todo/location_of_external_plugins.mdwn
+++ b/doc/todo/location_of_external_plugins.mdwn
@@ -28,5 +28,5 @@ As a side note, the accompanying proxy.py might better be placed into some direc
 >>> - Call ikiwiki using ``PYTHONPATH="$PYTHONPATH:/usr/lib/ikiwiki/plugins ikiwiki ...``, but it is a pain to write this each time I want to use this (and any solution like creating a custom script do not seem very nice);
 >>> - Make my plugin add `/usr/lib/ikiwiki/plugins` to its python path, but I do not know how portable this is for a non Debian distribution.
 >>>
->>> Any better idea (and sorry for digging up an old post).
+>>> Any better idea (and sorry for digging up an old post)?
 >>> -- [[Louis|spalax]]

Question about python path for external plugins.
diff --git a/doc/todo/location_of_external_plugins.mdwn b/doc/todo/location_of_external_plugins.mdwn
index c28003e..09f61da 100644
--- a/doc/todo/location_of_external_plugins.mdwn
+++ b/doc/todo/location_of_external_plugins.mdwn
@@ -22,3 +22,11 @@ As a side note, the accompanying proxy.py might better be placed into some direc
 >> external plugins means it's automatically in their `sys.path` without
 >> needing special configuration. --[[smcv]]
 >> (a mostly-inactive member of Debian's Python modules packaging team)
+
+>>> I mostly agree, but a problem arises when the external plugin we are using is not located in the same directory as the `proxy.py` file, but in a directory somewhere in a `libdir` or `libdirs` directory. Right now (for a soon-to-be published plugin I am working on) the solutions I am thinking about are:
+>>> 
+>>> - Call ikiwiki using ``PYTHONPATH="$PYTHONPATH:/usr/lib/ikiwiki/plugins ikiwiki ...``, but it is a pain to write this each time I want to use this (and any solution like creating a custom script do not seem very nice);
+>>> - Make my plugin add `/usr/lib/ikiwiki/plugins` to its python path, but I do not know how portable this is for a non Debian distribution.
+>>>
+>>> Any better idea (and sorry for digging up an old post).
+>>> -- [[Louis|spalax]]

http://i.imgur.com/0yo0VjC.png?1
diff --git a/doc/bugs/Missing_Element.mdwn b/doc/bugs/Missing_Element.mdwn
new file mode 100644
index 0000000..c8ee601
--- /dev/null
+++ b/doc/bugs/Missing_Element.mdwn
@@ -0,0 +1,7 @@
+I was thinking about using ikiwiki for a project I'm working on and was testing to see how fast the project loaded when I came across this error while testing the ikiwiki website using <https://www.dotcom-tools.com/website-speed-test.aspx>
+It said the following element was not found:
+Url: <https://ikiwiki.info/wikiicons/email.png>
+<https://ikiwiki.info/ikiwiki.cgi?do=prefs>
+
+
+<img src=http://i.imgur.com/0yo0VjC.png?1>

Idea: embedded podcast A/V player.
diff --git a/doc/todo/fancypodcast.mdwn b/doc/todo/fancypodcast.mdwn
index e26893e..fe75f58 100644
--- a/doc/todo/fancypodcast.mdwn
+++ b/doc/todo/fancypodcast.mdwn
@@ -26,6 +26,18 @@ Episode enclosure  |(./)      |(./)       |(./)        |(./)
 
 ## Future improvements
 
+### Embedded audio/video player in browsers
+
+* For a given enclosure, depending on autodetected MIME:
+    * `audio/*` -> `<audio>`
+    * `video/*` -> `<video>`
+* For a given template:
+    * `page.tmpl` -> eagerly fetch media
+    * `inlinepage.tmpl` -> fetch just enough to display durations
+* Only for HTML5 sites, or also okay for XHTML?
+* Does this work well enough in enough browsers, or do we need a
+  JavaScript player to fill in some gaps?
+
 ### iTunes fancy podcasting
 
 * [iTunes-specific tags](https://www.apple.com/itunes/podcasts/specs.html)

cloak user PII when making commits etc, and let cloaked PII be used in banned_users
This was needed due to emailauth, but I've also wrapped all IP address
exposure in cloak(), although the function doesn't yet cloak IP addresses.
(One IP address I didn't cloak is the one that appears on the password
reset email template. That is expected to be the user's own IP address,
so ok to show it to them.)
Thanks to smcv for the pointer to
http://xmlns.com/foaf/spec/#term_mbox_sha1sum
diff --git a/IkiWiki.pm b/IkiWiki.pm
index dfdd0fe..bb36b08 100644
--- a/IkiWiki.pm
+++ b/IkiWiki.pm
@@ -1430,6 +1430,7 @@ sub userpage ($) {
 	return length $config{userdir} ? "$config{userdir}/$user" : $user;
 }
 
+# Username to display for openid accounts.
 sub openiduser ($) {
 	my $user=shift;
 
@@ -1464,6 +1465,7 @@ sub openiduser ($) {
 	return;
 }
 
+# Username to display for emailauth accounts. 
 sub emailuser ($) {
 	my $user=shift;
 	if (defined $user && $user =~ m/(.+)@/) {
@@ -1475,6 +1477,22 @@ sub emailuser ($) {
 	return;
 }
 
+# Some user information should not be exposed in commit metadata, etc.
+# This generates a cloaked form of such information.
+sub cloak ($) {
+	my $user=shift;
+	# cloak email address using http://xmlns.com/foaf/spec/#term_mbox_sha1sum
+	if ($user=~m/(.+)@/) {
+		my $nick=$1;
+		eval q{use Digest::SHA};
+		return $user if $@;
+		return $nick.'@'.Digest::SHA::sha1_hex("mailto:$user");
+	}
+	else {
+		return $user;
+	}
+}
+
 sub htmlize ($$$$) {
 	my $page=shift;
 	my $destpage=shift;
diff --git a/IkiWiki/CGI.pm b/IkiWiki/CGI.pm
index d801c72..1763828 100644
--- a/IkiWiki/CGI.pm
+++ b/IkiWiki/CGI.pm
@@ -336,16 +336,19 @@ sub check_banned ($$) {
 
 	my $banned=0;
 	my $name=$session->param("name");
+	my $cloak=cloak($name) if defined $name;
 	if (defined $name && 
-	    grep { $name eq $_ } @{$config{banned_users}}) {
+	    grep { $name eq $_ || $cloak eq $_ } @{$config{banned_users}}) {
 		$banned=1;
 	}
 
 	foreach my $b (@{$config{banned_users}}) {
 		if (pagespec_match("", $b,
 			ip => $session->remote_addr(),
-			name => defined $name ? $name : "",
-		)) {
+			name => defined $name ? $name : "")
+		   || pagespec_match("", $b,
+		   	ip => cloak($session->remote_addr()),
+			name => defined $cloak ? $cloak : "")) {
 			$banned=1;
 			last;
 		}
diff --git a/IkiWiki/Plugin/bzr.pm b/IkiWiki/Plugin/bzr.pm
index e2b102d..5ec254f 100644
--- a/IkiWiki/Plugin/bzr.pm
+++ b/IkiWiki/Plugin/bzr.pm
@@ -133,10 +133,10 @@ sub bzr_author ($) {
 	my $ipaddr=$session->remote_addr();
 
 	if (defined $user) {
-		return IkiWiki::possibly_foolish_untaint($user);
+		return IkiWiki::possibly_foolish_untaint(IkiWiki::cloak($user));
 	}
 	elsif (defined $ipaddr) {
-		return "Anonymous from ".IkiWiki::possibly_foolish_untaint($ipaddr);
+		return "Anonymous from ".IkiWiki::possibly_foolish_untaint(IkiWiki::cloak($ipaddr));
 	}
 	else {
 		return "Anonymous";
diff --git a/IkiWiki/Plugin/comments.pm b/IkiWiki/Plugin/comments.pm
index eaa924e..ad813d1 100644
--- a/IkiWiki/Plugin/comments.pm
+++ b/IkiWiki/Plugin/comments.pm
@@ -466,7 +466,7 @@ sub editcomment ($$) {
 	my $content = "[[!comment format=$type\n";
 
 	if (defined $session->param('name')) {
-		my $username = $session->param('name');
+		my $username = IkiWiki::cloak($session->param('name'));
 		$username =~ s/"/&quot;/g;
 		$content .= " username=\"$username\"\n";
 	}
@@ -479,7 +479,7 @@ sub editcomment ($$) {
 
 	if (!(defined $session->param('name') || defined $session->param('nickname')) &&
 		defined $session->remote_addr()) {
-		$content .= " ip=\"".$session->remote_addr()."\"\n";
+		$content .= " ip=\"".IkiWiki::cloak($session->remote_addr())."\"\n";
 	}
 
 	if ($config{comments_allowauthor}) {
diff --git a/IkiWiki/Plugin/cvs.pm b/IkiWiki/Plugin/cvs.pm
index 841aec9..8989a26 100644
--- a/IkiWiki/Plugin/cvs.pm
+++ b/IkiWiki/Plugin/cvs.pm
@@ -456,12 +456,12 @@ sub commitmessage (@) {
 	if (defined $params{session}) {
 		if (defined $params{session}->param("name")) {
 			return "web commit by ".
-				$params{session}->param("name").
+				IkiWiki::cloak($params{session}->param("name")).
 				(length $params{message} ? ": $params{message}" : "");
 		}
 		elsif (defined $params{session}->remote_addr()) {
 			return "web commit from ".
-				$params{session}->remote_addr().
+				IkiWiki::cloak($params{session}->remote_addr()).
 				(length $params{message} ? ": $params{message}" : "");
 		}
 	}
diff --git a/IkiWiki/Plugin/darcs.pm b/IkiWiki/Plugin/darcs.pm
index 646f65d..9dccd95 100644
--- a/IkiWiki/Plugin/darcs.pm
+++ b/IkiWiki/Plugin/darcs.pm
@@ -147,10 +147,10 @@ sub commitauthor (@) {
 	my $author="anon\@web";
 	if (defined $params{session}) {
 		if (defined $params{session}->param("name")) {
-			return $params{session}->param("name").'@web';
+			return IkiWiki::cloak($params{session}->param("name")).'@web';
 		}
 		elsif (defined $params{session}->remote_addr()) {
-			return $params{session}->remote_addr().'@web';
+			return IkiWiki::cloak($params{session}->remote_addr()).'@web';
 		}
 	}
 	return 'anon@web';
diff --git a/IkiWiki/Plugin/git.pm b/IkiWiki/Plugin/git.pm
index 75b89e4..4d48388 100644
--- a/IkiWiki/Plugin/git.pm
+++ b/IkiWiki/Plugin/git.pm
@@ -579,7 +579,7 @@ sub rcs_commit_helper (@) {
 			$u=$params{session}->remote_addr();
 		}
 		if (defined $u) {
-			$u=encode_utf8($u);
+			$u=encode_utf8(IkiWiki::cloak($u));
 			$ENV{GIT_AUTHOR_NAME}=$u;
 		}
 		if (defined $params{session}->param("nickname")) {
diff --git a/IkiWiki/Plugin/mercurial.pm b/IkiWiki/Plugin/mercurial.pm
index 8da4ceb..9f0c5b7 100644
--- a/IkiWiki/Plugin/mercurial.pm
+++ b/IkiWiki/Plugin/mercurial.pm
@@ -183,10 +183,10 @@ sub rcs_commit_helper (@) {
 	my $user="Anonymous";
 	if (defined $params{session}) {
 		if (defined $params{session}->param("name")) {
-			$user = $params{session}->param("name");
+			$user = IkiWiki::cloak($params{session}->param("name"));
 		}
 		elsif (defined $params{session}->remote_addr()) {
-			$user = $params{session}->remote_addr();
+			$user = IkiWiki::cloak($params{session}->remote_addr());
 		}
 
 		my $nickname=$user;
diff --git a/IkiWiki/Plugin/monotone.pm b/IkiWiki/Plugin/monotone.pm
index 1056278..b0bba56 100644
--- a/IkiWiki/Plugin/monotone.pm
+++ b/IkiWiki/Plugin/monotone.pm
@@ -310,10 +310,10 @@ sub commitauthor (@) {
 
 	if (defined $params{session}) {
 		if (defined $params{session}->param("name")) {
-			return "Web user: " . $params{session}->param("name");
+			return "Web user: " . IkiWiki::cloak($params{session}->param("name"));
 		}
 		elsif (defined $params{session}->remote_addr()) {
-			return "Web IP: " . $params{session}->remote_addr();
+			return "Web IP: " . IkiWiki::cloak($params{session}->remote_addr());
 		}
 	}
 	return "Web: Anonymous";
diff --git a/IkiWiki/Plugin/svn.pm b/IkiWiki/Plugin/svn.pm
index fd11f2c..c46a52d 100644
--- a/IkiWiki/Plugin/svn.pm
+++ b/IkiWiki/Plugin/svn.pm
@@ -147,12 +147,12 @@ sub commitmessage (@) {
 	if (defined $params{session}) {
 		if (defined $params{session}->param("name")) {
 			return "web commit by ".

(Diff truncated)
comments
diff --git a/doc/todo/separate_authentication_from_authorization.mdwn b/doc/todo/separate_authentication_from_authorization.mdwn
index de7c5b7..389f014 100644
--- a/doc/todo/separate_authentication_from_authorization.mdwn
+++ b/doc/todo/separate_authentication_from_authorization.mdwn
@@ -35,6 +35,13 @@ Here is a sketch of a different account model that would address that:
     users with / in their names, which would make their user-page into a
     subpage?
 
+    > I have fixed passwordauth to not let urls be registered. It seems this
+    > was not quite a security hole; it didn't let registering a username that
+    > already existed, so if an openid was an admin, as long as the user logged
+    > in using that openid, someone else couldn't come along and passwordauth
+    > collide with it. (Might be exploitable if you could guess an openid that
+    > was going to be added as an admin later though.) --[[Joey]]
+
 * If passwordauth is enabled, accounts may have a password. Users can
   authenticate to an account that has a password by entering that password.
   The username is always the account name (because there's little reason
@@ -95,12 +102,6 @@ Thoughts?
 > 
 > Also, when you talk about "separating authentication from authorization", i immediately thought of [[todo/ACL/]] and [[todo/Zoned_ikiwiki/]], so i thought i could mention those... having stability in the usernames would help in the design of those... --[[anarcat]]
 
-> I'm not against this, but I don't anticipate having resources to do any
-> work on it either. --[[Joey]]
-
-> I have fixed passwordauth to not let urls be registered. It seems this
-> was not quite a security hole; it didn't let registering a name that
-> already existed, so if an openid was an admin, as long as the user logged
-> in using that openid, someone else couldn't come along and passwordauth
-> collide with it. (Might be exploitable if you could guess an openid that
-> was going to be added as an admin though.) --[[Joey]]
+> I'm not opposed to this, but I don't anticipate having resources to do any
+> work on it either. (I do hope to obscure email addresses from git
+> commits.) --[[Joey]]

passwordauth: Don't allow registering accounts that look like openids.
Also prohibit @ in account names, in case the file regexp was relaxed to
allow it.
diff --git a/IkiWiki/Plugin/passwordauth.pm b/IkiWiki/Plugin/passwordauth.pm
index 7c01bb3..3bdd9de 100644
--- a/IkiWiki/Plugin/passwordauth.pm
+++ b/IkiWiki/Plugin/passwordauth.pm
@@ -251,6 +251,12 @@ sub formbuilder_setup (@) {
 						my $name=shift;
 						length $name &&
 						$name=~/$config{wiki_file_regexp}/ &&
+						# don't allow registering
+						# accounts that look like
+						# openids, or email
+						# addresses, even if the
+						# file regexp allows it
+						$name!~/[\/:\@]/ &&
 						! IkiWiki::userinfo_get($name, "regdate");
 					},
 				);
diff --git a/debian/changelog b/debian/changelog
index 4580156..19f6dfb 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -9,6 +9,7 @@ ikiwiki (3.20150330) UNRELEASED; urgency=medium
     they don't have an openid.
   * Converted openid-selector into a more generic loginselector helper
     plugin.
+  * passwordauth: Don't allow registering accounts that look like openids.
 
  -- Joey Hess <id@joeyh.name>  Tue, 28 Apr 2015 12:24:08 -0400
 
diff --git a/doc/todo/separate_authentication_from_authorization.mdwn b/doc/todo/separate_authentication_from_authorization.mdwn
index 4a602ba..de7c5b7 100644
--- a/doc/todo/separate_authentication_from_authorization.mdwn
+++ b/doc/todo/separate_authentication_from_authorization.mdwn
@@ -94,3 +94,13 @@ Thoughts?
 > I always find it a little ackward that i have two different accounts on this wiki: one for OpenID, and the other (regular account) for email notifications (because of [[bugs/notifyemail_fails_with_some_openid_providers/]]). It seems to me those accounts should just be merged as one, ie. I was expecting to be able to choose a username when i registered with openid.
 > 
 > Also, when you talk about "separating authentication from authorization", i immediately thought of [[todo/ACL/]] and [[todo/Zoned_ikiwiki/]], so i thought i could mention those... having stability in the usernames would help in the design of those... --[[anarcat]]
+
+> I'm not against this, but I don't anticipate having resources to do any
+> work on it either. --[[Joey]]
+
+> I have fixed passwordauth to not let urls be registered. It seems this
+> was not quite a security hole; it didn't let registering a name that
+> already existed, so if an openid was an admin, as long as the user logged
+> in using that openid, someone else couldn't come along and passwordauth
+> collide with it. (Might be exploitable if you could guess an openid that
+> was going to be added as an admin though.) --[[Joey]]

Merge branch 'master' of ssh://git.ikiwiki.info
update re passwordauth @
diff --git a/doc/todo/emailauth.mdwn b/doc/todo/emailauth.mdwn
index aac2c98..88096be 100644
--- a/doc/todo/emailauth.mdwn
+++ b/doc/todo/emailauth.mdwn
@@ -62,7 +62,7 @@ Implementation notes:
   Otherwise, someone could use passwordauth to register as a username that
   looks like an email address, which would be confusing to possibly a
   security hole. Probably best to keep passwordauth and emailauth accounts
-  entirely distinct.
+  entirely distinct. Update: passwordauth never allowed `@` in usernames.
 * Currently, subscription to comments w/o registering is handled by
   passwordauth, by creating a passwordless account (making up a username,
   not using the email address as the username thankfully). That account can be

acls and expectations
diff --git a/doc/todo/separate_authentication_from_authorization.mdwn b/doc/todo/separate_authentication_from_authorization.mdwn
index b4a3604..4a602ba 100644
--- a/doc/todo/separate_authentication_from_authorization.mdwn
+++ b/doc/todo/separate_authentication_from_authorization.mdwn
@@ -90,3 +90,7 @@ of) that step to Mozilla.
 Thoughts?
 
 --[[smcv]]
+
+> I always find it a little ackward that i have two different accounts on this wiki: one for OpenID, and the other (regular account) for email notifications (because of [[bugs/notifyemail_fails_with_some_openid_providers/]]). It seems to me those accounts should just be merged as one, ie. I was expecting to be able to choose a username when i registered with openid.
+> 
+> Also, when you talk about "separating authentication from authorization", i immediately thought of [[todo/ACL/]] and [[todo/Zoned_ikiwiki/]], so i thought i could mention those... having stability in the usernames would help in the design of those... --[[anarcat]]

Critical of automatic merging of stylesheets
diff --git a/doc/todo/concatenating_or_compiling_CSS.mdwn b/doc/todo/concatenating_or_compiling_CSS.mdwn
index 068be93..8f35fb5 100644
--- a/doc/todo/concatenating_or_compiling_CSS.mdwn
+++ b/doc/todo/concatenating_or_compiling_CSS.mdwn
@@ -157,3 +157,25 @@ this without that feature initially.
 >>>
 >>> As you pointed out, CSS inclusion is more painful than it should be, and
 >>> your proposal seems to answer that. Go ahead! --[[Louis|spalax]]
+
+> Concatenating the theme css as is done now results in files that are
+> unecessarily large with a doubling of a lot of selectors etc. It only makes
+> sense for changes that should be local.css anyway. Catted css is inefficient
+> both while downloading and while rendering. I've disabled the catting in the
+> makefile to avoid this on my personal site. In my view it would be better for
+> theme developers to work from the basewiki style, if lazy just add their
+> changes to the end of it, or if speed is of secondary importance @import it. 
+> 
+> The advanced melding of stylesheets discussed sounds quite complicated with
+> likely useability problems when the site don't quite look as expected. Hunting
+> down the problematic css will be difficult.
+> 
+> Are there parsers that remove double defined selectors according to cascading
+> rules as is done in browser? This would at least produce cleaner css but the
+> useability problems would remain.
+> 
+> When using complete themes and hunting that last bit of speed a config option
+> to turn off local.css would probably be a good idea? Plugin css is difficult.
+> A choice between a plugin complete theme or a local.css (or @import from it)
+> would be a simple solution that lets you choose how you prioritize speed
+> vs convenience. --[[kjs]]

diff --git a/doc/todo/CSS:_Remove_fixed_height_from_actions.ul.mdwn b/doc/todo/CSS:_Remove_fixed_height_from_actions.ul.mdwn
new file mode 100644
index 0000000..44fa056
--- /dev/null
+++ b/doc/todo/CSS:_Remove_fixed_height_from_actions.ul.mdwn
@@ -0,0 +1,3 @@
+[[!template id=gitbranch branch=kjs/mobistyle author="[[kjs]]"]]
+Currently the bottom border cuts through the text on small devices. Resize your window to a narrow column to check.
+

please do cloak email addresses, the principle of least astonishment applies
diff --git a/doc/todo/emailauth.mdwn b/doc/todo/emailauth.mdwn
index aac2c98..4cf2e48 100644
--- a/doc/todo/emailauth.mdwn
+++ b/doc/todo/emailauth.mdwn
@@ -112,3 +112,23 @@ Thoughts anyone? --[[Joey]]
 >>
 >> Of course, spammers can troll git repos for emails anyway, so maybe
 >> this is fine. --[[Joey]]
+
+>>> I'm not so sure this is OK: user expectations for "a random wiki/blog"
+>>> are not the same as for direct git contributions. Common practice for
+>>> websites is for email addresses to be only available to the site owner
+>>> and/or outsourced services - if ikiwiki doesn't work like this,
+>>> I think wiki contributors/blog commenters are going to blame ikiwiki,
+>>> not themselves.
+>>>
+>>> One way to avoid this would be to
+>>> [[separate authentication from authorization]], so our account names
+>>> would be smcv and joey even on a purely emailauth wiki, with the
+>>> fact that we authenticate via email being an implementation detail.
+>>>
+>>> Another way to do it would be to hash the email address,
+>>> so the commit appears to come from
+>>> `smcv <smcv@dc84925053b18a910f4b95fb7ce1bf802eb7d80e>` instead of
+>>> from `smcv <smcv@debian.org>` - if the hash is of `mailto:whatever`
+>>> (like my example one) then it's compatible with
+>>> [FOAF](http://xmlns.com/foaf/spec/#term_mbox_sha1sum).
+>>> --[[smcv]]

proposal for making emailauth not force username == email address
diff --git a/doc/todo/separate_authentication_from_authorization.mdwn b/doc/todo/separate_authentication_from_authorization.mdwn
new file mode 100644
index 0000000..b4a3604
--- /dev/null
+++ b/doc/todo/separate_authentication_from_authorization.mdwn
@@ -0,0 +1,92 @@
+[[plugins/openid]] and the new [[plugins/emailauth]] both assume that
+the user's authentication identity (how they log in) is suitable as
+an authorization identity (who they are when they have logged in). In
+particular, the OpenID or email address goes into the git history.
+
+Relatedly, I'm not sure I'd be comfortable with enabling [[plugins/emailauth]]
+on my own sites while it writes users' email addresses into the git history:
+non-technical people (and many technical people for that matter) get
+possessive about who can know their email address. The usual expectation for
+email addresses on websites seems to be that they will be used by the site
+owner (and maybe their outsourced service providers), but not available
+to random third parties. The principle of least astonishment would suggest
+that we should do the same here.
+
+(The expectation of privacy for direct git commits is rather different:
+I think we can expect direct git committers to know that they
+should either set a plausible non-email-address in their git identity,
+like I used to use my OpenID, or have good spam filtering.)
+
+If we present email-based users in the "web UI" using only the local-part
+of their address, we also have a potentially confusing situation where
+`chris@example.com` and `chris@other.example.net` both contribute to a wiki:
+if I'm reading the code right, they'd both be presented as `chris`, with no
+way to change that other than using a different email address?
+
+Here is a sketch of a different account model that would address that:
+
+* An account has a username, e.g. `smcv`. It normally matches some regexp that
+  includes neither @ nor / (to rule out collisions with email addresses
+  and OpenIDs).
+
+  * We currently allow qr{-[:alnum:]+/.:_} by default, so passwordauth
+    accounts can in principle collide with OpenIDs. That would probably be
+    worth fixing (for new account creation) anyway - I don't think we want
+    users with / in their names, which would make their user-page into a
+    subpage?
+
+* If passwordauth is enabled, accounts may have a password. Users can
+  authenticate to an account that has a password by entering that password.
+  The username is always the account name (because there's little reason
+  to do anything else).
+
+* If httpauth is enabled, anyone who can authenticate to the web server
+  automatically gets access to the account of the same name in the wiki.
+  (Or we could consider having a configurable map
+  { web-server-level username => wiki account } but the default would be
+  an identity mapping.)
+
+* If OpenID is enabled, accounts may have an OpenID.
+  The owner of that OpenID can log in, and gets logged-in to that account.
+  Either reusing the same OpenID for multiple accounts is not allowed, or
+  if the same OpenID is attached to more than one account the user can choose
+  (as an extra step). Optionally, more than one OpenID could be allowed.
+
+* If emailauth is enabled, accounts may have an email address.
+  Users can authenticate to an account that has an email
+  address (and is not a grandfathered OpenID) by using the token challenge.
+  (passwordauth accounts could already do a password-reset, so this is not
+  any less secure.)
+
+* Creating an account from an email address (maybe also OpenID?) has a new
+  step: choosing a username, with some text about "this name will appear
+  in recentchanges and in the wiki's history". The default would be the
+  local-part (user) from the email address.
+
+* Grandfathered OpenID support: every existing account that looks like an
+  OpenID has that OpenID associated with it, and it cannot be changed or
+  removed. The displayed form is openiduser().
+
+* Grandfathered emailauth support, if required (but it might not be required
+  if we implement this model before the next ikiwiki release): every existing
+  account that looks like an email address has that email address associated
+  with it, and it cannot be changed or removed. The displayed form is
+  emailuser() but we should maybe change that to output something more
+  like `smcv@…`.
+
+* Hypothetically, an account could also have a https client certificate
+  for a new client-certificate plugin, or a Google account for a new OAuth2
+  plugin, or whatever, and all of the above applies equally.
+
+* Unlike the current OpenID support, if the user's authentication provider
+  goes away (or if Google stops doing OAuth2 and moves on to the next big
+  thing), they can associate a different authentication identity with
+  their existing wiki account, and continue.
+
+This is basically the same model that Mozilla Persona encourages,
+except using emailauth ourselves instead of outsourcing (the equivalent
+of) that step to Mozilla.
+
+Thoughts?
+
+--[[smcv]]

note about email visibility in git commits
diff --git a/doc/plugins/emailauth.mdwn b/doc/plugins/emailauth.mdwn
index 8cb060e..db22e29 100644
--- a/doc/plugins/emailauth.mdwn
+++ b/doc/plugins/emailauth.mdwn
@@ -11,7 +11,8 @@ some other form of authentication, such as [[passwordauth]] or [[openid]].
 Users who have logged in using emailauth will have their email address used as
 their username. In places where the username is displayed, like the
 RecentChanges page, the domain will be omitted, to avoid exposing the
-user's email address.
+user's email address. Note though that the email address will be visible
+when looking at eg, commits in the git repository.
 
 This plugin needs the [[!cpan Mail::SendMail]] perl module installed,
 and able to send outgoing email.

fix page extension
diff --git a/doc/plugins/emailauth.mdwn b/doc/plugins/emailauth.mdwn
new file mode 100644
index 0000000..8cb060e
--- /dev/null
+++ b/doc/plugins/emailauth.mdwn
@@ -0,0 +1,17 @@
+[[!template id=plugin name=emailauth core=1 author="[[Joey]]"]]
+[[!tag type/auth]]
+
+This plugin lets users log into ikiwiki using any email address. To complete
+the login, a one-time-use link is emailed to the user, and they can simply
+open that link in their browser.
+
+It is enabled by default, but can be turned off if you want to only use
+some other form of authentication, such as [[passwordauth]] or [[openid]].
+
+Users who have logged in using emailauth will have their email address used as
+their username. In places where the username is displayed, like the
+RecentChanges page, the domain will be omitted, to avoid exposing the
+user's email address.
+
+This plugin needs the [[!cpan Mail::SendMail]] perl module installed,
+and able to send outgoing email.
diff --git a/doc/plugins/emailauth.pm b/doc/plugins/emailauth.pm
deleted file mode 100644
index 8cb060e..0000000
--- a/doc/plugins/emailauth.pm
+++ /dev/null
@@ -1,17 +0,0 @@
-[[!template id=plugin name=emailauth core=1 author="[[Joey]]"]]
-[[!tag type/auth]]
-
-This plugin lets users log into ikiwiki using any email address. To complete
-the login, a one-time-use link is emailed to the user, and they can simply
-open that link in their browser.
-
-It is enabled by default, but can be turned off if you want to only use
-some other form of authentication, such as [[passwordauth]] or [[openid]].
-
-Users who have logged in using emailauth will have their email address used as
-their username. In places where the username is displayed, like the
-RecentChanges page, the domain will be omitted, to avoid exposing the
-user's email address.
-
-This plugin needs the [[!cpan Mail::SendMail]] perl module installed,
-and able to send outgoing email.

close
diff --git a/doc/todo/emailauth.mdwn b/doc/todo/emailauth.mdwn
index fa19957..aac2c98 100644
--- a/doc/todo/emailauth.mdwn
+++ b/doc/todo/emailauth.mdwn
@@ -103,3 +103,12 @@ Thoughts anyone? --[[Joey]]
 > I had looked at something like this before, through [[todo/indyauth_support]] - which basically turned out to outsource their own auth to http://intridea.github.io/omniauth/ and http://indiewebcamp.com/RelMeAuth...
 > 
 > But it seems to me that your proposal is basic "email opt-in".. the one impact this has on (drupal) sites i know is that spammers use even those forms to send random emails to users. it's weird, but it seems that some bots simply try to shove victim's emails into forms with the spam data as they can and hope for the best... it seems this could be vulnerable as well... - [[anarcat]]
+
+>> Implemented now. [[done]]
+>> 
+>> Only thing that we might want to revisit sometime is that the email address
+>> is used in git commits. While it won't be displayed on any static wiki 
+>> pages (AFAICS), spammers could find it in the git commit log.
+>>
+>> Of course, spammers can troll git repos for emails anyway, so maybe
+>> this is fine. --[[Joey]]

emailauth link sent and verified; user login works
Still some work to do since the user name is an email address and should
not be leaked.
diff --git a/IkiWiki/Plugin/emailauth.pm b/IkiWiki/Plugin/emailauth.pm
index 3946ace..3266e21 100644
--- a/IkiWiki/Plugin/emailauth.pm
+++ b/IkiWiki/Plugin/emailauth.pm
@@ -8,6 +8,7 @@ use IkiWiki 3.00;
 
 sub import {
 	hook(type => "getsetup", id => "emailauth", "call" => \&getsetup);
+	hook(type => "cgi", id => "cgi", "call" => \&cgi);
 	IkiWiki::loadplugin("loginselector");
 	IkiWiki::Plugin::loginselector::register_login_plugin(
 		"emailauth",
@@ -41,17 +42,119 @@ sub email_check_input ($) {
 		&& length $cgi->param('Email_entry');
 }
 
-sub email_auth ($$$) {
+# Send login link to email.
+sub email_auth ($$$$) {
 	my $cgi=shift;
 	my $session=shift;
 	my $errordisplayer=shift;
-	
-	unless ($cgi->param('Email_entry') =~ /.\@./) {
-		$errordisplayer->("Invalid email address.");
+	my $infodisplayer=shift;
+
+	my $email=$cgi->param('Email_entry');
+	unless ($email =~ /.\@./) {
+		$errordisplayer->(gettext("Invalid email address."));
 		return;
 	}
 
-	error "EMAIL AUTH";
+	# Implicit account creation.
+	my $userinfo=IkiWiki::userinfo_retrieve();
+	if (! exists $userinfo->{$email} || ! ref $userinfo->{$email}) {
+		IkiWiki::userinfo_setall($email, {
+			'email' => $email,
+			'regdate' => time,
+		});
+	}
+
+	my $token=gentoken($email);
+	my $template=template("emailauth.tmpl");
+	$template->param(
+		wikiname => $config{wikiname},
+		# Intentionally using short field names to keep link short.
+		authurl => IkiWiki::cgiurl_abs(
+			'e' => $email,
+			'v' => $token,
+		),
+	);
+	
+	eval q{use Mail::Sendmail};
+	error($@) if $@;
+	sendmail(
+		To => $email,
+		From => "$config{wikiname} admin <".
+			(defined $config{adminemail} ? $config{adminemail} : "")
+			.">",
+		Subject => "$config{wikiname} login",
+		Message => $template->output,
+	) or error(gettext("Failed to send mail"));
+
+	$infodisplayer->(gettext("You have been sent an email, with a link you can open to complete the login process."));
+}
+
+# Finish login process.
+sub cgi ($$) {
+	my $cgi=shift;
+
+	my $email=$cgi->param('e');
+	my $v=$cgi->param('v');
+	if (defined $email && defined $v && length $email && length $v) {
+		# Need to lock the wiki before getting a session.
+		IkiWiki::lockwiki();
+		IkiWiki::loadindex();
+		my $session=IkiWiki::cgi_getsession();
+
+		my $token=gettoken($email);
+		if ($token eq $v) {
+			print STDERR "SUCCESS $email!!\n";
+			cleartoken($email);
+			$session->param(name => $email);
+			my $nickname=$email;
+			$nickname=~s/@.*//;
+			$session->param(nickname => Encode::decode_utf8($nickname));
+			IkiWiki::cgi_postsignin($cgi, $session);
+		}
+		elsif (length $token ne length $cgi->param('v')) {
+			error(gettext("Wrong login token length. Please check that you pasted in the complete login link from the email!"));
+		}
+		else {
+			loginfailure();
+		}
+	}
+}
+
+# Generates the token that will be used in the authurl to log the user in.
+# This needs to be hard to guess, and relatively short. Generating a cgi
+# session id will make it as hard to guess as any cgi session.
+sub gentoken ($) {
+	my $email=shift;
+	eval q{use CGI::Session};
+	error($@) if $@;
+	my $token = CGI::Session->new->id;
+	# Store token in userinfo; this allows the user to log in
+	# using a different browser session, if it takes a while for the
+	# email to get to them.
+	IkiWiki::userinfo_set($email, "emailauthexpire", time+(60*60*24));
+	IkiWiki::userinfo_set($email, "emailauth", $token);
+	return $token;
+}
+
+# Gets the token, checking for expiry.
+sub gettoken ($) {
+	my $email=shift;
+	my $val=IkiWiki::userinfo_get($email, "emailauth");
+	my $expire=IkiWiki::userinfo_get($email, "emailauthexpire");
+	if (! length $val || time > $expire) {
+		loginfailure();
+	}
+	return $val;
+}
+
+sub cleartoken ($) {
+	my $email=shift;
+	IkiWiki::userinfo_set($email, "emailauthexpire", 0);
+	IkiWiki::userinfo_set($email, "emailauth", "");
+}
+
+sub loginfailure () {
+	error "Bad email authentication token. Please retry login.";
 }
 
 1
diff --git a/IkiWiki/Plugin/loginselector.pm b/IkiWiki/Plugin/loginselector.pm
index 1a322a5..26c80b4 100644
--- a/IkiWiki/Plugin/loginselector.pm
+++ b/IkiWiki/Plugin/loginselector.pm
@@ -21,12 +21,13 @@ sub register_login_plugin ($$$$) {
 	# This sub is passed a cgi object, and should return true
 	# if it looks like the user is logging in using the plugin.
 	my $plugin_check_input=shift;
-	# This sub is passed a cgi object, a session object, and an error
-	# display callback, and should handle the actual authentication.
-	# It can either exit w/o returning, if it is able to handle
-	# auth, or it can pass an error message to the error display
-	# callback to make the openid selector form be re-disiplayed with
-	# an error message on it.
+	# This sub is passed a cgi object, a session object, an error
+	# display callback, and an info display callback, and should
+	# handle the actual authentication. It can either exit w/o
+	# returning, if it is able to handle auth, or it can pass an
+	# error message to the error display callback to make the
+	# openid selector form be re-disiplayed with an error message
+	# on it.
 	my $plugin_auth=shift;
 	$login_plugins{$plugin_name}={
 		setup => $plugin_setup,
@@ -56,6 +57,8 @@ sub login_selector {
 		if ($login_plugins{$plugin}->{check_input}->($q)) {
 			$login_plugins{$plugin}->{auth}->($q, $session, sub {
 				$template->param(login_error => shift());
+			}, sub {
+				$template->param(login_info => shift());
 			});
 			last;
 		}
diff --git a/IkiWiki/Plugin/openid.pm b/IkiWiki/Plugin/openid.pm
index 67b8cd3..cc4b4ba 100644
--- a/IkiWiki/Plugin/openid.pm
+++ b/IkiWiki/Plugin/openid.pm
@@ -63,7 +63,7 @@ sub openid_check_input ($) {
 	defined $q->param("action") && $q->param("action") eq "verify" && defined $openid_url && length $openid_url;
 }
 
-sub openid_auth ($$$) {
+sub openid_auth ($$$$) {
 	my $q=shift;
 	my $session=shift;
 	my $errordisplayer=shift;
diff --git a/doc/plugins/emailauth.pm b/doc/plugins/emailauth.pm
index 9ba26e4..8cb060e 100644
--- a/doc/plugins/emailauth.pm
+++ b/doc/plugins/emailauth.pm
@@ -12,3 +12,6 @@ Users who have logged in using emailauth will have their email address used as
 their username. In places where the username is displayed, like the
 RecentChanges page, the domain will be omitted, to avoid exposing the
 user's email address.
+
+This plugin needs the [[!cpan Mail::SendMail]] perl module installed,
+and able to send outgoing email.
diff --git a/templates/login-selector.tmpl b/templates/login-selector.tmpl
index 9b68838..3e7045c 100644
--- a/templates/login-selector.tmpl
+++ b/templates/login-selector.tmpl
@@ -48,6 +48,9 @@ $(document).ready(function() {
 		<TMPL_IF LOGIN_ERROR>

(Diff truncated)
add emailauth.tmpl
diff --git a/doc/templates.mdwn b/doc/templates.mdwn
index 525b4f8..c45316e 100644
--- a/doc/templates.mdwn
+++ b/doc/templates.mdwn
@@ -92,8 +92,9 @@ Here is a full list of the template files used:
 * `editpage.tmpl`, `editconflict.tmpl`, `editcreationconflict.tmpl`,
   `editfailedsave.tmpl`, `editpagegone.tmpl`, `pocreatepage.tmpl`,
   `editcomment.tmpl` `commentmoderation.tmpl`, `renamesummary.tmpl`,
-  `passwordmail.tmpl`, `login-selector.tmpl`, `revert.tmpl` - Parts of ikiwiki's user
-  interface; do not normally need to be customised.
+  `passwordmail.tmpl`, `emailauth.tmpl, `login-selector.tmpl`, 
+  `revert.tmpl` - Parts of ikiwiki's user interface; do not normally need
+  to be customised.
 
 
 [[!meta robots="noindex, follow"]]
diff --git a/templates/emailauth.tmpl b/templates/emailauth.tmpl
new file mode 100644
index 0000000..51fbb40
--- /dev/null
+++ b/templates/emailauth.tmpl
@@ -0,0 +1,11 @@
+To log into <TMPL_VAR WIKINAME>, just open the following link:
+
+<TMPL_VAR AUTHURL>
+
+This link can only be used once to log in, and will expire in one day.
+
+If you were not trying to log into <TMPL_VAR WIKINAME>, please
+disregard this email.
+
+-- 
+ikiwiki

email auth plugin now works through email address entry
diff --git a/IkiWiki/Plugin/emailauth.pm b/IkiWiki/Plugin/emailauth.pm
new file mode 100644
index 0000000..62c9fe8
--- /dev/null
+++ b/IkiWiki/Plugin/emailauth.pm
@@ -0,0 +1,64 @@
+#!/usr/bin/perl
+# Ikiwiki email address as login
+package IkiWiki::Plugin::emailauth;
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+
+sub import {
+	hook(type => "getsetup", id => "emailauth", "call" => \&getsetup);
+	hook(type => "auth", id => "emailauth", call => \&auth);
+	IkiWiki::loadplugin("loginselector");
+	IkiWiki::Plugin::loginselector::register_login_plugin(
+		"emailauth",
+		\&email_setup,
+		\&email_check_input,
+		\&email_auth,
+	);
+}
+
+sub getsetup () {
+	return
+		plugin => {
+			safe => 1,
+			rebuild => 0,
+			section => "auth",
+		},
+}
+
+sub email_setup ($$) {
+	my $q=shift;
+	my $template=shift;
+
+	return 1;
+}
+
+sub email_check_input ($) {
+	my $cgi=shift;
+	defined $cgi->param('do')
+		&& $cgi->param("do") eq "signin"
+		&& defined $cgi->param('Email_entry')
+		&& length $cgi->param('Email_entry');
+}
+
+sub email_auth ($$$) {
+	my $cgi=shift;
+	my $session=shift;
+	my $errordisplayer=shift;
+	
+	unless ($cgi->param('Email_entry') =~ /.\@./) {
+		$errordisplayer->("Invalid email address.");
+		return;
+	}
+
+	error "EMAIL AUTH";
+}
+
+sub auth ($$) {
+	# While this hook is not currently used, it needs to exist
+	# so ikiwiki knows that the wiki supports logins, and will
+	# enable the Preferences page.
+}
+
+1
diff --git a/doc/plugins/emailauth.pm b/doc/plugins/emailauth.pm
new file mode 100644
index 0000000..9ba26e4
--- /dev/null
+++ b/doc/plugins/emailauth.pm
@@ -0,0 +1,14 @@
+[[!template id=plugin name=emailauth core=1 author="[[Joey]]"]]
+[[!tag type/auth]]
+
+This plugin lets users log into ikiwiki using any email address. To complete
+the login, a one-time-use link is emailed to the user, and they can simply
+open that link in their browser.
+
+It is enabled by default, but can be turned off if you want to only use
+some other form of authentication, such as [[passwordauth]] or [[openid]].
+
+Users who have logged in using emailauth will have their email address used as
+their username. In places where the username is displayed, like the
+RecentChanges page, the domain will be omitted, to avoid exposing the
+user's email address.

Converted openid-selector into a more generic loginselector helper plugin.
diff --git a/IkiWiki/Plugin/loginselector.pm b/IkiWiki/Plugin/loginselector.pm
new file mode 100644
index 0000000..b5e2056
--- /dev/null
+++ b/IkiWiki/Plugin/loginselector.pm
@@ -0,0 +1,121 @@
+#!/usr/bin/perl
+package IkiWiki::Plugin::loginselector;
+
+use warnings;
+use strict;
+use IkiWiki 3.00;
+
+# Plugins that provide login methods can register themselves here.
+# Note that the template and js file also have be be modifed to add a new
+# login method.
+our %login_plugins;
+
+sub register_login_plugin ($$$$) {
+	# Same as the name of the plugin that is registering itself as a
+	# login plugin. eg, "openid"
+	my $plugin_name=shift;
+	# This sub is passed a cgi object and a template object which it
+	# can manipulate. It should return true if the plugin can be used
+	# (it might load necessary modules for auth checking, for example).
+	my $plugin_setup=shift;
+	# This sub is passed a cgi object, and should return true
+	# if it looks like the user is logging in using the plugin.
+	my $plugin_check_input=shift;
+	# This sub is passed a cgi object, a session object, and an error
+	# display callback, and should handle the actual authentication.
+	# It can either exit w/o returning, if it is able to handle
+	# auth, or it can pass an error message to the error display
+	# callback to make the openid selector form be re-disiplayed with
+	# an error message on it.
+	my $plugin_auth=shift;
+	$login_plugins{$plugin_name}={
+		setup => $plugin_setup,
+		check_input => $plugin_check_input,
+		auth => $plugin_auth,
+	};
+}
+
+sub login_selector {
+	my $real_cgi_signin=shift;
+	my $otherform_label=shift;
+	my $q=shift;
+	my $session=shift;
+
+	my $template=IkiWiki::template("login-selector.tmpl");
+
+	foreach my $plugin (keys %login_plugins) {
+		if (! $login_plugins{$plugin}->{setup}->($template)) {
+			delete $login_plugins{$plugin};
+		}
+		else {
+			$template->param("login_selector_$plugin", 1);
+		}
+	}
+
+	foreach my $plugin (keys %login_plugins) {
+		if ($login_plugins{$plugin}->{check_input}->($q)) {
+			$login_plugins{$plugin}->{auth}->($q, $session, sub {
+				$template->param(login_error => shift());
+			});
+			last;
+		}
+	}
+
+	$template->param(
+		cgiurl => IkiWiki::cgiurl(),
+		($real_cgi_signin ? (otherform => $real_cgi_signin->($q, $session, 1)) : ()),
+		otherform_label => $otherform_label,
+	);
+
+	IkiWiki::printheader($session);
+	print IkiWiki::cgitemplate($q, "signin", $template->output);
+	exit;
+}
+
+sub import {
+	add_underlay("login-selector");
+	add_underlay("jquery");
+	hook(type => "getsetup", id => "loginselector",  call => \&getsetup);
+	hook(type => "checkconfig", id => "loginselector", call => \&checkconfig);
+}
+
+sub checkconfig () {
+	if ($config{cgi}) {
+		# Intercept normal signin form, so the login selector
+		# can be displayed.
+		# 
+		# When other auth hooks are registered, give the selector
+		# a reference to the normal signin form.
+		require IkiWiki::CGI;
+		my $real_cgi_signin;
+		my $otherform_label=gettext("Other");
+		if (keys %{$IkiWiki::hooks{auth}} > 1) {
+			$real_cgi_signin=\&IkiWiki::cgi_signin;
+			my %h=%{$IkiWiki::hooks{auth}};
+			foreach my $p (keys %login_plugins) {
+				delete $h{$p};
+			}
+			# Special case to avoid labeling password auth as
+			# "Other" when it's the only auth plugin not
+			# integrated with the loginselector.
+			if (keys %h == 1 && exists $h{passwordauth}) {
+				$otherform_label=gettext("Password");
+			}
+		}
+		inject(name => "IkiWiki::cgi_signin", call => sub ($$) {
+			login_selector($real_cgi_signin, $otherform_label, @_);
+		});
+	}
+}
+
+sub getsetup () {
+	return
+		plugin => {
+			# this plugin is safe but only makes sense as a
+			# dependency
+			safe => 0,
+			rebuild => 0,
+		},
+}
+
+1
diff --git a/IkiWiki/Plugin/openid.pm b/IkiWiki/Plugin/openid.pm
index a12c83b..67b8cd3 100644
--- a/IkiWiki/Plugin/openid.pm
+++ b/IkiWiki/Plugin/openid.pm
@@ -7,38 +7,17 @@ use strict;
 use IkiWiki 3.00;
 
 sub import {
-	add_underlay("login-selector");
-	add_underlay("jquery");
-	hook(type => "checkconfig", id => "openid", call => \&checkconfig);
 	hook(type => "getsetup", id => "openid", call => \&getsetup);
 	hook(type => "auth", id => "openid", call => \&auth);
 	hook(type => "formbuilder_setup", id => "openid",
 		call => \&formbuilder_setup, last => 1);
-}
-
-sub checkconfig () {
-	if ($config{cgi}) {
-		# Intercept normal signin form, so the openid selector
-		# can be displayed.
-		# 
-		# When other auth hooks are registered, give the selector
-		# a reference to the normal signin form.
-		require IkiWiki::CGI;
-		my $real_cgi_signin;
-		my $otherform_label=gettext("Other");
-		if (keys %{$IkiWiki::hooks{auth}} > 1) {
-			$real_cgi_signin=\&IkiWiki::cgi_signin;
-			my %h=%{$IkiWiki::hooks{auth}};
-			delete $h{openid};
-			delete $h{emailauth};
-			if (keys %h == 1 && exists $h{passwordauth}) {
-				$otherform_label=gettext("Password");
-			}
-		}
-		inject(name => "IkiWiki::cgi_signin", call => sub ($$) {
-			openid_selector($real_cgi_signin, $otherform_label, @_);
-		});
-	}
+	IkiWiki::loadplugin("loginselector");
+	IkiWiki::Plugin::loginselector::register_login_plugin(
+		"openid",
+		\&openid_setup,
+		\&openid_check_input,
+		\&openid_auth,
+	);
 }
 
 sub getsetup () {
@@ -62,40 +41,34 @@ sub getsetup () {
 		},
 }
 
-sub openid_selector {
-	my $real_cgi_signin=shift;
-	my $otherform_label=shift;
-        my $q=shift;
-        my $session=shift;
-
-	my $template=IkiWiki::template("login-selector.tmpl");
-	my $openid_url=$q->param('openid_identifier');
+sub openid_setup ($$) {
+	my $q=shift;
+	my $template=shift;
 
-	if (! load_openid_module()) {
-		if ($real_cgi_signin) {
-			$real_cgi_signin->($q, $session);
-			exit;
+	if (load_openid_module()) {
+		my $openid_url=$q->param('openid_identifier');
+		if (defined $openid_url) {

(Diff truncated)
rename openid selector files to login-selector
diff --git a/IkiWiki/Plugin/openid.pm b/IkiWiki/Plugin/openid.pm
index b8ebbe2..a12c83b 100644
--- a/IkiWiki/Plugin/openid.pm
+++ b/IkiWiki/Plugin/openid.pm
@@ -7,7 +7,7 @@ use strict;
 use IkiWiki 3.00;
 
 sub import {
-	add_underlay("openid-selector");
+	add_underlay("login-selector");
 	add_underlay("jquery");
 	hook(type => "checkconfig", id => "openid", call => \&checkconfig);
 	hook(type => "getsetup", id => "openid", call => \&getsetup);
@@ -68,7 +68,7 @@ sub openid_selector {
         my $q=shift;
         my $session=shift;
 
-	my $template=IkiWiki::template("openid-selector.tmpl");
+	my $template=IkiWiki::template("login-selector.tmpl");
 	my $openid_url=$q->param('openid_identifier');
 
 	if (! load_openid_module()) {
diff --git a/debian/copyright b/debian/copyright
index a73d1cc..35fadf5 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -201,20 +201,20 @@ Comment:
  Republished with permission.
 License: GPL-2+
 
-Files: underlays/openid-selector/ikiwiki/openid/*
+Files: underlays/openid-selector/ikiwiki/login-selector/*
 Copyright: © 2008-2010 andyjm, david.j.boden
 Comment: 
  From http://code.google.com/p/openid-selector/
 License: BSD-2-clause
 
-Files: underlays/openid-selector/ikiwiki/openid/goa-*
+Files: underlays/openid-selector/ikiwiki/login-selector/goa-*
 Copyright:
  © 2011 Red Hat, Inc.
 License: LGPL-2.1+
 Comment:
  taken from data/icons/16x16/ in gnome-online-accounts git
 
-Files: underlays/openid-selector/ikiwiki/openid/wordpress.png
+Files: underlays/openid-selector/ikiwiki/login-selector/wordpress.png
 Copyright:
  © 2003-2013 "the contributors"
 License: GPL-2+
@@ -226,9 +226,8 @@ Files:
  icons/aol.svg
  icons/livejournal.svg
  icons/verisign.svg
- underlays/openid-selector/ikiwiki/openid/aol.png
- underlays/openid-selector/ikiwiki/openid/livejournal.png
- underlays/openid-selector/ikiwiki/openid/verisign.png
+ underlays/openid-selector/ikiwiki/login-selector/aol.png
+ underlays/openid-selector/ikiwiki/login-selector/verisign.png
 Copyright:
  © 2014 Simon McVittie
 License: other
diff --git a/doc/basewiki.mdwn b/doc/basewiki.mdwn
index 8392884..b4aa60c 100644
--- a/doc/basewiki.mdwn
+++ b/doc/basewiki.mdwn
@@ -10,7 +10,7 @@ It currently includes these pages:
 * [[templates]]
 * [[ikiwiki/formatting]]
 * [[ikiwiki/markdown]]
-* [[ikiwiki/openid]]
+* [[ikiwiki/login-selector]]
 * [[ikiwiki/pagespec]]
 * [[ikiwiki/directive]]
 * [[ikiwiki/subpage]]
diff --git a/doc/templates.mdwn b/doc/templates.mdwn
index 80372fc..525b4f8 100644
--- a/doc/templates.mdwn
+++ b/doc/templates.mdwn
@@ -92,7 +92,7 @@ Here is a full list of the template files used:
 * `editpage.tmpl`, `editconflict.tmpl`, `editcreationconflict.tmpl`,
   `editfailedsave.tmpl`, `editpagegone.tmpl`, `pocreatepage.tmpl`,
   `editcomment.tmpl` `commentmoderation.tmpl`, `renamesummary.tmpl`,
-  `passwordmail.tmpl`, `openid-selector.tmpl`, `revert.tmpl` - Parts of ikiwiki's user
+  `passwordmail.tmpl`, `login-selector.tmpl`, `revert.tmpl` - Parts of ikiwiki's user
   interface; do not normally need to be customised.
 
 
diff --git a/templates/login-selector.tmpl b/templates/login-selector.tmpl
new file mode 100644
index 0000000..e3a91fe
--- /dev/null
+++ b/templates/login-selector.tmpl
@@ -0,0 +1,62 @@
+<script type="text/javascript" src="ikiwiki/jquery.min.js"></script>
+<script type="text/javascript" src="ikiwiki/login-selector/login-selector.js"></script>
+<script type="text/javascript">
+$(document).ready(function() {
+	selector.init(
+		'openid_identifier',
+		{
+			<TMPL_IF LOGIN_SELECTOR_OPENID>'openid': 1,</TMPL_IF>
+			<TMPL_IF LOGIN_SELECTOR_EMAIL>'email': 1,</TMPL_IF>
+		},
+		'<TMPL_IF OTHERFORM>otherform</TMPL_IF>',
+		'<TMPL_VAR OTHERFORM_LABEL>'
+	);
+});
+</script>
+
+<form action="<TMPL_VAR CGIURL>" method="get" id="login_selector_form">
+	<div>
+		<script>
+		$('fieldset').append("<legend>Select login method</legend>");
+		</script>
+		
+		<input type="hidden" name="do" value="signin" />
+		<input type="hidden" name="action" value="verify" />
+		<div id="login_choice">
+			<div id="login_btns"></div>
+		</div>
+
+		<div id="login_input_area">
+		<div>
+		<h3>OpenId login:</h3>
+		<TMPL_IF LOGIN_SELECTOR_OPENID>
+			<label for="openid_identifier" class="block">Enter your OpenID:</label>
+			<input id="openid_identifier" name="openid_identifier" type="text" value="<TMPL_VAR ESCAPE=HTML OPENID_URL>"/>
+			<input id="openid_submit" type="submit" value="Login"/>
+		</TMPL_IF>
+		</div>
+		<div>
+		<h3>Email login:</h3>
+		<TMPL_IF LOGIN_SELECTOR_EMAIL>
+			<label for="email_address" class="block">Enter your email address:</label>
+			<input id="email_address" name="Email_entry" type="text" value="<TMPL_VAR ESCAPE=HTML EMAIL_ADDRESS>"/>
+			<input id="email_submit" type="submit" value="Login"/>
+		</TMPL_IF>
+		</div>
+		</div>
+
+		<TMPL_IF LOGIN_ERROR>
+		<div class="error"><TMPL_VAR LOGIN_ERROR></div>
+		</TMPL_IF>
+	</div>
+</form>
+
+<div id="otherform">
+<TMPL_IF OTHERFORM>
+<br />
+<noscript>
+<h3><TMPL_VAR OTHERFORM_LABEL> login:</h3>
+</noscript>
+</TMPL_IF>
+<TMPL_VAR OTHERFORM>
+</div>
diff --git a/templates/openid-selector.tmpl b/templates/openid-selector.tmpl
deleted file mode 100644
index a055203..0000000
--- a/templates/openid-selector.tmpl
+++ /dev/null
@@ -1,62 +0,0 @@
-<script type="text/javascript" src="ikiwiki/jquery.min.js"></script>
-<script type="text/javascript" src="ikiwiki/openid/openid-jquery.js"></script>
-<script type="text/javascript">
-$(document).ready(function() {
-	selector.init(
-		'openid_identifier',
-		{
-			<TMPL_IF LOGIN_SELECTOR_OPENID>'openid': 1,</TMPL_IF>
-			<TMPL_IF LOGIN_SELECTOR_EMAIL>'email': 1,</TMPL_IF>
-		},
-		'<TMPL_IF OTHERFORM>otherform</TMPL_IF>',
-		'<TMPL_VAR OTHERFORM_LABEL>'
-	);
-});
-</script>
-
-<form action="<TMPL_VAR CGIURL>" method="get" id="login_selector_form">
-	<div>
-		<script>
-		$('fieldset').append("<legend>Select login method</legend>");
-		</script>
-		
-		<input type="hidden" name="do" value="signin" />
-		<input type="hidden" name="action" value="verify" />
-		<div id="login_choice">
-			<div id="login_btns"></div>
-		</div>
-
-		<div id="login_input_area">
-		<div>
-		<h3>OpenId login:</h3>
-		<TMPL_IF LOGIN_SELECTOR_OPENID>
-			<label for="openid_identifier" class="block">Enter your OpenID:</label>
-			<input id="openid_identifier" name="openid_identifier" type="text" value="<TMPL_VAR ESCAPE=HTML OPENID_URL>"/>
-			<input id="openid_submit" type="submit" value="Login"/>
-		</TMPL_IF>
-		</div>
-		<div>

(Diff truncated)
comments
diff --git a/doc/todo/indyauth_support.mdwn b/doc/todo/indyauth_support.mdwn
index 51389ad..1dec103 100644
--- a/doc/todo/indyauth_support.mdwn
+++ b/doc/todo/indyauth_support.mdwn
@@ -1,3 +1,12 @@
 this looks pretty awesome: <https://indieauth.com/>
 
 anyone working on a plugin or has ideas on how to implement this? --[[anarcat]]
+
+> My understanding of indyauth is that the wiki owner would need to pick an
+> indyauth provider, which handles the communication with the Big Silos.
+> 
+> I guess the wiki owner could run their own, but they'd be more likely to
+> run the one provided by the indyauth people. So, this is effectively
+> centralized, although without lock-in.
+> 
+> Also, see related <https://indiecert.net/>  --[[Joey]]

generalized the openid selector to a login selector
This includes some CSS changes to names of elements.
Also, added Email login button (doesn't work yet of course),
and brought back the small openid login buttons. Demoted yahoo and verison
to small buttons. This makes the big buttons be the main login types, and
the small buttons be provider-specific helpers.
diff --git a/IkiWiki/Plugin/openid.pm b/IkiWiki/Plugin/openid.pm
index 00652eb..bfd130a 100644
--- a/IkiWiki/Plugin/openid.pm
+++ b/IkiWiki/Plugin/openid.pm
@@ -25,15 +25,18 @@ sub checkconfig () {
 		# a reference to the normal signin form.
 		require IkiWiki::CGI;
 		my $real_cgi_signin;
-		my $nonopenidform_label=gettext("Other");
+		my $otherform_label=gettext("Other");
 		if (keys %{$IkiWiki::hooks{auth}} > 1) {
 			$real_cgi_signin=\&IkiWiki::cgi_signin;
-			if (keys %{$IkiWiki::hooks{auth}} == 2 && exists $IkiWiki::hooks{auth}->{passwordauth}) {
-				$nonopenidform_label=gettext("Password");
+			my %h=%{$IkiWiki::hooks{auth}};
+			delete $h{openid};
+			delete $h{emailauth};
+			if (keys %h == 1 && exists $h{passwordauth}) {
+				$otherform_label=gettext("Password");
 			}
 		}
 		inject(name => "IkiWiki::cgi_signin", call => sub ($$) {
-			openid_selector($real_cgi_signin, $nonopenidform_label, @_);
+			openid_selector($real_cgi_signin, $otherform_label, @_);
 		});
 	}
 }
@@ -61,12 +64,12 @@ sub getsetup () {
 
 sub openid_selector {
 	my $real_cgi_signin=shift;
-	my $nonopenidform_label=shift;
+	my $otherform_label=shift;
         my $q=shift;
         my $session=shift;
 
+	my $template=IkiWiki::template("openid-selector.tmpl");
 	my $openid_url=$q->param('openid_identifier');
-	my $openid_error;
 
 	if (! load_openid_module()) {
 		if ($real_cgi_signin) {
@@ -75,19 +78,17 @@ sub openid_selector {
 		}
 		error(sprintf(gettext("failed to load openid module: "), @_));
 	}
-	elsif (defined $q->param("action") && $q->param("action") eq "verify") {
+	elsif (defined $q->param("action") && $q->param("action") eq "verify" && defined $openid_url && length $openid_url) {
 		validate($q, $session, $openid_url, sub {
-			$openid_error=shift;
+			$template->param(login_error => shift())
 		});
 	}
 
-	my $template=IkiWiki::template("openid-selector.tmpl");
 	$template->param(
 		cgiurl => IkiWiki::cgiurl(),
-		(defined $openid_error ? (openid_error => $openid_error) : ()),
 		(defined $openid_url ? (openid_url => $openid_url) : ()),
-		($real_cgi_signin ? (nonopenidform => $real_cgi_signin->($q, $session, 1)) : ()),
-		nonopenidform_label => $nonopenidform_label,
+		($real_cgi_signin ? (otherform => $real_cgi_signin->($q, $session, 1)) : ()),
+		otherform_label => $otherform_label,
 	);
 
 	IkiWiki::printheader($session);
diff --git a/doc/style.css b/doc/style.css
index fe1eb90..f0846c0 100644
--- a/doc/style.css
+++ b/doc/style.css
@@ -465,40 +465,40 @@ li.L8 { list-style: upper-alpha; }
 	display: none;
 }
 
-/* openid selector */
-#openid_choice {
+/* login selector */
+#login_choice {
 	display: none;
 }
-#openid_input_area {
+#login_input_area {
 	clear: both;
 	padding: 10px;
 }
-#openid_btns, #openid_btns br {
+#login_btns, #login_btns br {
 	clear: both;
 }
-#openid_highlight {
+#login_highlight {
 	background-color: black;
 	float: left;
 }
-.openid_large_btn {
+.login_large_btn {
 	padding: 1em 1.5em;
 	border: 1px solid #DDD;
 	margin: 3px;
 	float: left;
 }
-.openid_small_btn {
+.login_small_btn {
 	padding: 4px 4px;
 	border: 1px solid #DDD;
 	margin: 3px;
 	float: left;
 }
-a.openid_large_btn:focus {
+a.login_large_btn:focus {
 	outline: none;
 }
-a.openid_large_btn:focus {
+a.login_large_btn:focus {
 	outline-style: none;
 }
-.openid_selected {
+.login_selected {
 	border: 4px solid #DDD;
 }
 
diff --git a/doc/wikiicons/emaillogin.png b/doc/wikiicons/emaillogin.png
new file mode 100644
index 0000000..1b16bef
Binary files /dev/null and b/doc/wikiicons/emaillogin.png differ
diff --git a/templates/openid-selector.tmpl b/templates/openid-selector.tmpl
index 95ba086..03eb5d7 100644
--- a/templates/openid-selector.tmpl
+++ b/templates/openid-selector.tmpl
@@ -2,42 +2,42 @@
 <script type="text/javascript" src="ikiwiki/openid/openid-jquery.js"></script>
 <script type="text/javascript">
 $(document).ready(function() {
-	openid.init('openid_identifier','<TMPL_IF NONOPENIDFORM>nonopenidform</TMPL_IF>', '<TMPL_VAR NONOPENIDFORM_LABEL>');
+	selector.init('openid_identifier','<TMPL_IF OTHERFORM>otherform</TMPL_IF>', '<TMPL_VAR OTHERFORM_LABEL>');
 });
 </script>
 
 <noscript>
-<h2>OpenID:</h2>
+<h2>Login:</h2>
 </noscript>
 
-<form action="<TMPL_VAR CGIURL>" method="get" id="openid_form">
-	<fieldset>
+<form action="<TMPL_VAR CGIURL>" method="get" id="login_selector_form">
+	<div>
 		<script>
 		$('fieldset').append("<legend>Select login method</legend>");
 		</script>
 		
 		<input type="hidden" name="do" value="signin" />
 		<input type="hidden" name="action" value="verify" />
-		<div id="openid_choice">
-			<div id="openid_btns"></div>
+		<div id="login_choice">
+			<div id="login_btns"></div>
 		</div>
-		<div id="openid_input_area">
+		<div id="login_input_area">
 			<label for="openid_identifier" class="block">Enter your OpenID:</label>
 			<input id="openid_identifier" name="openid_identifier" type="text" value="<TMPL_VAR ESCAPE=HTML OPENID_URL>"/>
 			<input id="openid_submit" type="submit" value="Login"/>
 		</div>
-		<TMPL_IF OPENID_ERROR>
-		<div class="error"><TMPL_VAR OPENID_ERROR></div>
+		<TMPL_IF LOGIN_ERROR>
+		<div class="error"><TMPL_VAR LOGIN_ERROR></div>
 		</TMPL_IF>
-	</fieldset>
+	</div>
 </form>
 
-<div id="nonopenidform">
-<TMPL_IF NONOPENIDFORM>
+<div id="otherform">
+<TMPL_IF OTHERFORM>
 <br />
 <noscript>
-<h2><TMPL_VAR NONOPENIDFORM_LABEL>:</h2>
+<h2><TMPL_VAR OTHERFORM_LABEL>:</h2>
 </noscript>
 </TMPL_IF>
-<TMPL_VAR NONOPENIDFORM>
+<TMPL_VAR OTHERFORM>
 </div>
diff --git a/underlays/openid-selector/ikiwiki/openid/aol.png b/underlays/openid-selector/ikiwiki/openid/aol.png
new file mode 100644
index 0000000..d47f5fa
Binary files /dev/null and b/underlays/openid-selector/ikiwiki/openid/aol.png differ
diff --git a/underlays/openid-selector/ikiwiki/openid/goa-account-flickr.png b/underlays/openid-selector/ikiwiki/openid/goa-account-flickr.png
new file mode 100644
index 0000000..5321642
Binary files /dev/null and b/underlays/openid-selector/ikiwiki/openid/goa-account-flickr.png differ
diff --git a/underlays/openid-selector/ikiwiki/openid/livejournal.png b/underlays/openid-selector/ikiwiki/openid/livejournal.png
new file mode 100644
index 0000000..d86ee5e
Binary files /dev/null and b/underlays/openid-selector/ikiwiki/openid/livejournal.png differ
diff --git a/underlays/openid-selector/ikiwiki/openid/openid-jquery.js b/underlays/openid-selector/ikiwiki/openid/openid-jquery.js
index 2c72f19..db8dca2 100644

(Diff truncated)
link to indieauth and mention existing problems with this approach
diff --git a/doc/todo/emailauth.mdwn b/doc/todo/emailauth.mdwn
index a164b78..fa19957 100644
--- a/doc/todo/emailauth.mdwn
+++ b/doc/todo/emailauth.mdwn
@@ -99,3 +99,7 @@ adminusers can be converted, perhaps automatically, to use the email
 addresses on record.
 
 Thoughts anyone? --[[Joey]]
+
+> I had looked at something like this before, through [[todo/indyauth_support]] - which basically turned out to outsource their own auth to http://intridea.github.io/omniauth/ and http://indiewebcamp.com/RelMeAuth...
+> 
+> But it seems to me that your proposal is basic "email opt-in".. the one impact this has on (drupal) sites i know is that spammers use even those forms to send random emails to users. it's weird, but it seems that some bots simply try to shove victim's emails into forms with the spam data as they can and hope for the best... it seems this could be vulnerable as well... - [[anarcat]]

thoughts
diff --git a/doc/todo/emailauth.mdwn b/doc/todo/emailauth.mdwn
index bf139cf..a164b78 100644
--- a/doc/todo/emailauth.mdwn
+++ b/doc/todo/emailauth.mdwn
@@ -72,4 +72,30 @@ Implementation notes:
 * Adapting the passwordauth reset code is probably the simplest way to
   implement emailauth. That uses a CGI::Session id as the entropy.
 
+----
+
+So this all seems doable. What I'm unsure about is this: Is emailauth going
+to be sufficiently easier than passwordauth that it will let users
+contribute to wikis who otherwise wouldn't?
+
+Using passwordauth, the user can register by just picking a password, and
+username, and entering email. That's 2 more things that need to be entered,
+but then there is no need to wait for an email link to arrive. Which can
+take a while, or be an unreliable, opaque process for users.
+
+OTOH, maybe some users don't want to have to make up a username and
+password, or pchycologically don't want to register. emailauth would then
+let them contiribute.
+
+I also have a motivation for ikiwiki-hosting/branchable. That needs the
+user to be able to log into the site, create their own wiki, and then log
+into their own wiki. Currently, openid is the only way to do that;
+emailauth would be another way.
+
+Another motivation from ikiwiki-hosting/branchable is that with google
+openid going away, many sites can have only google openids as adminusers, and
+that has to be manually dealt with. But if emailauth is added, those
+adminusers can be converted, perhaps automatically, to use the email
+addresses on record.
+
 Thoughts anyone? --[[Joey]]

tyo
diff --git a/doc/todo/emailauth.mdwn b/doc/todo/emailauth.mdwn
index 05b7f11..bf139cf 100644
--- a/doc/todo/emailauth.mdwn
+++ b/doc/todo/emailauth.mdwn
@@ -67,7 +67,7 @@ Implementation notes:
   passwordauth, by creating a passwordless account (making up a username,
   not using the email address as the username thankfully). That account can be
   upgraded to a passworded account if the user follows a link in comment
-  mails to login. So there is considerable overhead between that and
+  mails to login. So there is considerable overlap between that and
   emailauth.
 * Adapting the passwordauth reset code is probably the simplest way to
   implement emailauth. That uses a CGI::Session id as the entropy.

update
diff --git a/doc/todo/emailauth.mdwn b/doc/todo/emailauth.mdwn
index bd94287..05b7f11 100644
--- a/doc/todo/emailauth.mdwn
+++ b/doc/todo/emailauth.mdwn
@@ -31,13 +31,14 @@ A few points to make this more secure:
 Still, this could be attacked:
 
 * If an attacker can access a user's inbox, they can generate a new login
-  link, and log in as them.
+  link, and log in as them. They are probably busy draining their bank
+  account by this method and not logging into some wiki though.
 * If TLS is not used for the email transport, a MITM can snoop login links
-  and use them.
+  and use them. Again probably more lucrative ways to exploit such a MITM.
 * If https is not used for the login link, a MITM can intercept and proxy
   web traffic and either steal a copy of the cookie, or use the login
   link themselves without letting the user log in. This attack seems no
-  worse then using password authentication w/o https, and the solution is
+  worse than using password authentication w/o https, and the solution is
   of course https.
 * If an attacker wants to DOS a wiki, they can try to get its domain, IP,
   whatever blacklisted as a spam source.

update
diff --git a/doc/todo/emailauth.mdwn b/doc/todo/emailauth.mdwn
index fa3d26b..bd94287 100644
--- a/doc/todo/emailauth.mdwn
+++ b/doc/todo/emailauth.mdwn
@@ -3,13 +3,20 @@ be dying on the vine, and no other replacements looking very likely (except
 for Oauth type stuff perhaps), it would be good to have a new easy way to
 log into ikiwiki, that doesn't need pre-registration.
 
-I've read about email being used this way, and seen it once or twice. While I
-can't remember any links right now, the basic idea is:
+Importantly, I want something that is not going to go
+the way of openid in the future. I think that email is here to stay; at
+least anyone who wants an email address is going to be able to get one in
+the forseeable future. (Google and large providers are making it harder to
+run small email systems, but it's still very possible, and there are at
+worst many large providers.)
+
+I've read about email being used for login auth, and seen it once or twice.
+While I can't remember any links right now, the basic idea is:
 
 1. user enters email address into form
 2. response page says "a login link has been emailed to you"
 3. user opens email and clicks login link
-4. user is logged in
+4. user is logged in until the cookie expires or is cleared
 
 A few points to make this more secure:
 

proposal
diff --git a/doc/todo/emailauth.mdwn b/doc/todo/emailauth.mdwn
new file mode 100644
index 0000000..fa3d26b
--- /dev/null
+++ b/doc/todo/emailauth.mdwn
@@ -0,0 +1,67 @@
+With many users no longer having an openid account, and Persona seeming to
+be dying on the vine, and no other replacements looking very likely (except
+for Oauth type stuff perhaps), it would be good to have a new easy way to
+log into ikiwiki, that doesn't need pre-registration.
+
+I've read about email being used this way, and seen it once or twice. While I
+can't remember any links right now, the basic idea is:
+
+1. user enters email address into form
+2. response page says "a login link has been emailed to you"
+3. user opens email and clicks login link
+4. user is logged in
+
+A few points to make this more secure:
+
+* Only 1 login link should be active at a time; old ones won't work to log in.
+* A login link is only valid for a single login. Once it's used, it cannot
+  be used to log in again.
+* A login link is only valid for a certain period of time. 24 hours seems
+  like more than enough, and 12 hours would probably be plenty too.
+  This timeout means a user doesn't need to worry about their email
+  archives being used to log in.
+
+Still, this could be attacked:
+
+* If an attacker can access a user's inbox, they can generate a new login
+  link, and log in as them.
+* If TLS is not used for the email transport, a MITM can snoop login links
+  and use them.
+* If https is not used for the login link, a MITM can intercept and proxy
+  web traffic and either steal a copy of the cookie, or use the login
+  link themselves without letting the user log in. This attack seems no
+  worse then using password authentication w/o https, and the solution is
+  of course https.
+* If an attacker wants to DOS a wiki, they can try to get its domain, IP,
+  whatever blacklisted as a spam source.
+
+These attacks don't seem worth not doing it; many of the same attacks can
+be performed against openid, or passwordauth. Eg, reset password and
+intercept email.
+
+Implementation notes:
+
+* Use the email address as the username.
+* Sanitize the email for display in recentchanges etc.
+* The login link should be as short an url as possible, while containing
+  sufficient entropy. Some email clients will let the user click on it,
+  but some users will need to cut and paste.
+* The `adminemail` config setting has a bit of overlap with an `adminuser`
+  set to an email address. Probably worth keeping them separae though;
+  the `adminemail` is an email address to display, and we may not want to
+  let anyone who can read the adminemail's mailbox to log into the wiki.
+* Will want to make passwordauth reject registrations that contain `@`.
+  Otherwise, someone could use passwordauth to register as a username that
+  looks like an email address, which would be confusing to possibly a
+  security hole. Probably best to keep passwordauth and emailauth accounts
+  entirely distinct.
+* Currently, subscription to comments w/o registering is handled by
+  passwordauth, by creating a passwordless account (making up a username,
+  not using the email address as the username thankfully). That account can be
+  upgraded to a passworded account if the user follows a link in comment
+  mails to login. So there is considerable overhead between that and
+  emailauth.
+* Adapting the passwordauth reset code is probably the simplest way to
+  implement emailauth. That uses a CGI::Session id as the entropy.
+
+Thoughts anyone? --[[Joey]]

close
diff --git a/doc/todo/remove_Google_from_OpenID_selector_unless_grandfathered.mdwn b/doc/todo/remove_Google_from_OpenID_selector_unless_grandfathered.mdwn
index 87b82fe..2c06845 100644
--- a/doc/todo/remove_Google_from_OpenID_selector_unless_grandfathered.mdwn
+++ b/doc/todo/remove_Google_from_OpenID_selector_unless_grandfathered.mdwn
@@ -11,3 +11,5 @@ should be an option: default _off_, can be turned _on_ for an established ikiwik
 instance that is known to be grandfathered.
 
 -- [[jcflack]]
+
+> Oh well, it's dead and gone now. [[done]] --[[Joey]]

branch link fix
diff --git a/doc/users/kjs.mdwn b/doc/users/kjs.mdwn
index 2c8553d..325d748 100644
--- a/doc/users/kjs.mdwn
+++ b/doc/users/kjs.mdwn
@@ -7,16 +7,18 @@ Websites using ikiwiki:
 * <http://stockholm.kalleswork.net>
 
 
-[[!template id=gitbranch branch=kjs/master author="[[Kalle Söderman|kjs]]"]]
+[[!template id=gitbranch branch=kjs/kalleswork.net author="[[Kalle Söderman|kjs]]"]]
 
 Mostly using ikiwiki with the [[/plugins/contrib/album/]] and [[plugins/osm]]
 plugins. My git repo with tweaks including the simplebw theme and various
 changes to the [[plugins/contrib/album]] plugin and templates can be found in
-my master branch
+my kalleswork.net branch
 
-Note that the master brach is all my changes piled into one branch. **I can't
-code (clone my repo above if you don't believe me!) so noone should run my
-code without checking it first.** I can't stress this enough.
+Note that the kalleswork.net branch is all my changes piled into one branch
+that I compile to run my sites. 
+
+**I can't code (clone my repo above if you don't believe me!) so noone should
+run my code without checking it first.** I can't stress this enough.
 
 The main changes I've done are the following
 

local.css also blocking
diff --git a/doc/bugs/Eliminate_render-blocking_JavaScript.mdwn b/doc/bugs/Eliminate_render-blocking_JavaScript.mdwn
index 6df0408..6a10178 100644
--- a/doc/bugs/Eliminate_render-blocking_JavaScript.mdwn
+++ b/doc/bugs/Eliminate_render-blocking_JavaScript.mdwn
@@ -7,3 +7,7 @@ I've tried disabling [[plugins/relativedate]], [[plugins/toggle]] & even [[plugi
 <img src=http://s.natalian.org/2015-05-11/1431321269_1054x1058.png>
 
 I am a bit at a loss now. Any ideas?
+
+> Can't help with the specific question but you won't get higher rating than
+> 85 due to the local.css link.[img.kalleswork.net pagespeed
+> results](https://developers.google.com/speed/pagespeed/insights/?url=http%3A%2F%2Fimg.kalleswork.net) -[[kjs]]

can't work this out
diff --git a/doc/bugs/Eliminate_render-blocking_JavaScript.mdwn b/doc/bugs/Eliminate_render-blocking_JavaScript.mdwn
new file mode 100644
index 0000000..6df0408
--- /dev/null
+++ b/doc/bugs/Eliminate_render-blocking_JavaScript.mdwn
@@ -0,0 +1,9 @@
+Hi there, I'm trying to remove the render blocking Javascript from the [ikiwiki/branchable](http://webconverger.org/ikiwiki.cgi?do=branchable) site <https://developers.google.com/speed/pagespeed/insights/?url=http%3A%2F%2Fwebconverger.org%2F>
+
+<img src=http://s.natalian.org/2015-05-11/1431321125_1054x1058.png>
+
+I've tried disabling [[plugins/relativedate]], [[plugins/toggle]] & even [[plugins/goodstuff]], but STILL there is being JS embedded in my test site <http://sg.webconverger.com/>:
+
+<img src=http://s.natalian.org/2015-05-11/1431321269_1054x1058.png>
+
+I am a bit at a loss now. Any ideas?

Add "Aloodo Blog"
diff --git a/doc/ikiwikiusers.mdwn b/doc/ikiwikiusers.mdwn
index 24c1af8..7fa405e 100644
--- a/doc/ikiwikiusers.mdwn
+++ b/doc/ikiwikiusers.mdwn
@@ -206,3 +206,4 @@ Personal sites and blogs
 * [James Technotes](http://jamestechnotes.com), my [wiki](http://jamestechnotes.com) and [blog](http://jamestechnotes.com/blog).
 * [Amitai Schlair's site](http://www.schmonz.com/)
 * My ([[spalax]]) [professional website](http://paternault.fr)
+* [Aloodo Blog](http://blog.aloodo.org/)

Added a comment: You are right
diff --git a/doc/forum/Ikiwiki_themes_for_mobile_devices__63__/comment_3_cc449f49196d455e0da464a7905ef49a._comment b/doc/forum/Ikiwiki_themes_for_mobile_devices__63__/comment_3_cc449f49196d455e0da464a7905ef49a._comment
new file mode 100644
index 0000000..0cf8818
--- /dev/null
+++ b/doc/forum/Ikiwiki_themes_for_mobile_devices__63__/comment_3_cc449f49196d455e0da464a7905ef49a._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="http://hendry.iki.fi/"
+ nickname="Kai Hendry"
+ subject="You are right"
+ date="2015-05-10T02:22:27Z"
+ content="""
+Sorry, I was using my own local.css and page.tmpl that was exacerbating the issue.
+"""]]

Added a comment
diff --git a/doc/forum/Ikiwiki_themes_for_mobile_devices__63__/comment_2_769be04c9579dcb3c4d1bb1d1bb78661._comment b/doc/forum/Ikiwiki_themes_for_mobile_devices__63__/comment_2_769be04c9579dcb3c4d1bb1d1bb78661._comment
new file mode 100644
index 0000000..4cdaa75
--- /dev/null
+++ b/doc/forum/Ikiwiki_themes_for_mobile_devices__63__/comment_2_769be04c9579dcb3c4d1bb1d1bb78661._comment
@@ -0,0 +1,9 @@
+[[!comment format=mdwn
+ username="smcv"
+ subject="comment 2"
+ date="2015-05-09T07:06:01Z"
+ content="""
+Recent ikiwiki is meant to scale down to phone sizes using similar techniques,
+although it isn't fully there yet. Further patches to style.css would be
+very welcome...
+"""]]

Fix Archlinux link
diff --git a/doc/download.mdwn b/doc/download.mdwn
index 100f728..61167e3 100644
--- a/doc/download.mdwn
+++ b/doc/download.mdwn
@@ -46,4 +46,4 @@ Gentoo has an [ebuild](http://bugs.gentoo.org/show_bug.cgi?id=144453) in its bug
 
 The [openSUSE Build Service](http://software.opensuse.org/search?baseproject=ALL&p=1&q=ikiwiki) has packages for openSUSE
 
-A [PKGBUILD for Arch Linux](http://aur.archlinux.org/packages.php?ID=12284) is in the AUR.
+A [PKGBUILD for Arch Linux](https://aur.archlinux.org/packages/ikiwiki/) is in the AUR.

Added a comment: Going mobile
diff --git a/doc/forum/Ikiwiki_themes_for_mobile_devices__63__/comment_1_ff5442b7e119878f24724d5bb47975cf._comment b/doc/forum/Ikiwiki_themes_for_mobile_devices__63__/comment_1_ff5442b7e119878f24724d5bb47975cf._comment
new file mode 100644
index 0000000..dba9086
--- /dev/null
+++ b/doc/forum/Ikiwiki_themes_for_mobile_devices__63__/comment_1_ff5442b7e119878f24724d5bb47975cf._comment
@@ -0,0 +1,17 @@
+[[!comment format=mdwn
+ username="http://hendry.iki.fi/"
+ nickname="Kai Hendry"
+ subject="Going mobile"
+ date="2015-05-08T06:39:19Z"
+ content="""
+Hello Mikko,
+
+Thank you for sharing! I like what you have done. Needs some more work according to Google mind:
+
+* <https://www.google.com/webmasters/tools/mobile-friendly/?url=https%3A%2F%2Fmcfrisk.kapsi.fi%2Fskiing%2F>
+* <http://shallowsky.com/blog/tech/web/google-mobile-friendly.html>
+
+We need to \"mobilize\" ikiwiki.info. And then I need to fix my own site: <http://webconverger.org/> !!
+
+
+"""]]

Using ikiwiki for a new podcast.
diff --git a/doc/users/schmonz.mdwn b/doc/users/schmonz.mdwn
index fac5c94..efa3bb6 100644
--- a/doc/users/schmonz.mdwn
+++ b/doc/users/schmonz.mdwn
@@ -9,6 +9,7 @@ pages="!*/Discussion and ((link(users/schmonz) and plugins/* and !plugins/openid
 ## Public
 
 * [My personal web site](http://www.schmonz.com/)
+* [A very small podcast](http://agilein3minutes.com/)
 * [A major open-source project's wiki](http://wiki.netbsd.org) (with
   the [[rcs/cvs]] plugin)
 * [An undergraduate group's university-provided-static-hosted

underlay plugin needs to be enabled of course
diff --git a/doc/todo/git-annex_support.mdwn b/doc/todo/git-annex_support.mdwn
index 5e0a363..342319c 100644
--- a/doc/todo/git-annex_support.mdwn
+++ b/doc/todo/git-annex_support.mdwn
@@ -222,6 +222,8 @@ And we need the following config:
 hardlink: 1
 add_underlays:
 - /home/w-anarcat/annex
+add_plugins:
+- underlay
 </pre>
 
 ... and the `ikiwiki-hosting` patch mentionned earlier to allow git-annex-shell to run at all. Also, the `--shared` option will [make git-annex use hardlinks itself between the two repos](https://git-annex.branchable.com/todo/wishlist:_use_hardlinks_for_local_clones/), so the files will be available for download as well. --[[anarcat]]

Yes to leaflet.js
diff --git a/doc/todo/replace_openlayers_with_leaflet/discussion.mdwn b/doc/todo/replace_openlayers_with_leaflet/discussion.mdwn
index 6223e1d..0c59655 100644
--- a/doc/todo/replace_openlayers_with_leaflet/discussion.mdwn
+++ b/doc/todo/replace_openlayers_with_leaflet/discussion.mdwn
@@ -1,3 +1,6 @@
 Would this be replacing openlayers in the osm plugin? Or writing a new plugin that can use leaflet (and possibly other libraries including OpenLayers 3?) ?
 
 > I think the module should be split in two: one part could simply make an inventory of waypoints and generate GIS files (.csv, .kml, etc). Another could render the map based on those files, and that could be made with leaflet. -- [[anarcat]]
+
+Enabling leaflet sounds like a great idea. I've been pining for this since I
+started using the osm plugin! -- [[kjs]]

Looking again at fancying up podcasts for iTunes.
diff --git a/doc/todo/fancypodcast.mdwn b/doc/todo/fancypodcast.mdwn
index 1280170..e26893e 100644
--- a/doc/todo/fancypodcast.mdwn
+++ b/doc/todo/fancypodcast.mdwn
@@ -30,8 +30,12 @@ Episode enclosure  |(./)      |(./)       |(./)        |(./)
 
 * [iTunes-specific tags](https://www.apple.com/itunes/podcasts/specs.html)
   appear to be RSS-only
-    * If they work in Atom, teach `inline` to optionally iTunesify RSS/Atom.
-    * Else, add `itunes` as a third kind of feed (RSS plus more stuff).
+    * Can we always include them in RSS feeds, or would that break
+      some feed readers?
+    * Is it even valid to include them in Atom feeds? If so, do
+      Atom podcasts look any better in podcatchers?
+    * Avoid adding a third kind of feed (`itunesrss`), or options
+      to the existing `rss` and `atom` feeds, unless we have to.
 * Notable tags for feeds:
     * `itunes:subtitle`
     * `itunes:author`
@@ -47,6 +51,9 @@ Episode enclosure  |(./)      |(./)       |(./)        |(./)
         * [ffprobe](http://ffmpeg.org/ffprobe.html) is reasonably fast
         * [mediainfo](http://mediainfo.sourceforge.net/) is way slower
         * Cache computed durations as pagestate
+* [Podcast Feed Best
+  Practice](https://github.com/gpodder/podcast-feed-best-practice/blob/master/podcast-feed-best-practice.md)
+  from the gPodder folks
 
 ### Fancy podcast aggregating
 

split it
diff --git a/doc/todo/replace_openlayers_with_leaflet/discussion.mdwn b/doc/todo/replace_openlayers_with_leaflet/discussion.mdwn
index 9e6eb91..6223e1d 100644
--- a/doc/todo/replace_openlayers_with_leaflet/discussion.mdwn
+++ b/doc/todo/replace_openlayers_with_leaflet/discussion.mdwn
@@ -1 +1,3 @@
 Would this be replacing openlayers in the osm plugin? Or writing a new plugin that can use leaflet (and possibly other libraries including OpenLayers 3?) ?
+
+> I think the module should be split in two: one part could simply make an inventory of waypoints and generate GIS files (.csv, .kml, etc). Another could render the map based on those files, and that could be made with leaflet. -- [[anarcat]]

Start discussion regarding OpenLayers 2
diff --git a/doc/todo/replace_openlayers_with_leaflet/discussion.mdwn b/doc/todo/replace_openlayers_with_leaflet/discussion.mdwn
new file mode 100644
index 0000000..9e6eb91
--- /dev/null
+++ b/doc/todo/replace_openlayers_with_leaflet/discussion.mdwn
@@ -0,0 +1 @@
+Would this be replacing openlayers in the osm plugin? Or writing a new plugin that can use leaflet (and possibly other libraries including OpenLayers 3?) ?

diff --git a/doc/todo/replace_openlayers_with_leaflet.mdwn b/doc/todo/replace_openlayers_with_leaflet.mdwn
index f042ad0..837d914 100644
--- a/doc/todo/replace_openlayers_with_leaflet.mdwn
+++ b/doc/todo/replace_openlayers_with_leaflet.mdwn
@@ -1,3 +1,3 @@
-Openlayers is *huge*! At 200k lines of code and 450KB, it is a significant overhead on a GIS-enabled modest ikiwiki site. It would be good to consider switching to [Leaflet](http://leafletjs.com/) which is only 123KB ([source](https://en.wikipedia.org/wiki/Leaflet_(software)#Comparison_with_other_libraries)).
+Openlayers is *huge*! At 200k lines of code and 450KB, it is a significant overhead on a GIS-enabled modest ikiwiki site. It would be good to consider switching to [Leaflet](http://leafletjs.com/) which is only 123KB ([source](https://en.wikipedia.org/wiki/Leaflet_(software))).
 
 This would imply rewriting osm.js and probably bits of osm.pm, but would give us significant gains in performance... Leaflet is used by Flickr, Wikimedia, the main OpenStreemap map site and many others. --[[anarcat]]

still works here, thanks to version pinning
diff --git a/doc/bugs/osm_plugin_fails_to_display_map_with_javascript_error.mdwn b/doc/bugs/osm_plugin_fails_to_display_map_with_javascript_error.mdwn
index bc92e80..45a746e 100644
--- a/doc/bugs/osm_plugin_fails_to_display_map_with_javascript_error.mdwn
+++ b/doc/bugs/osm_plugin_fails_to_display_map_with_javascript_error.mdwn
@@ -10,3 +10,13 @@ The javascript errors I saw are:
 	osm.js (line 30, col 1)
 
 --[[Joey]]
+
+> I guess OpenLayers made a backwards-incompatible change... At [reseaulibre](http://wiki.reseaulibre.ca/) it seems we have survived this because we have a local copy of the OpenLayers source code:
+> 
+>         osm_openlayers_url: http://wiki.reseaulibre.ca/OpenLayers-2.12/OpenLayers.js
+>
+> Try specifying a versionned URL for the source:
+>
+>         osm_openlayers_url: http://openlayers.org/api/2.12/OpenLayers.js
+> 
+> ... and see if that fixes the problem. Then we can start looking at the [release notes](https://github.com/openlayers/openlayers/blob/master/notes/2.13.md) to figure out what change they did that broke us and upgrade. Or pin the version on our side. Or simply [[switch to something else|todo/replace_openlayers_with_leaflet]]. --[[anarcat]]

diff --git a/doc/todo/replace_openlayers_with_leaflet.mdwn b/doc/todo/replace_openlayers_with_leaflet.mdwn
new file mode 100644
index 0000000..f042ad0
--- /dev/null
+++ b/doc/todo/replace_openlayers_with_leaflet.mdwn
@@ -0,0 +1,3 @@
+Openlayers is *huge*! At 200k lines of code and 450KB, it is a significant overhead on a GIS-enabled modest ikiwiki site. It would be good to consider switching to [Leaflet](http://leafletjs.com/) which is only 123KB ([source](https://en.wikipedia.org/wiki/Leaflet_(software)#Comparison_with_other_libraries)).
+
+This would imply rewriting osm.js and probably bits of osm.pm, but would give us significant gains in performance... Leaflet is used by Flickr, Wikimedia, the main OpenStreemap map site and many others. --[[anarcat]]

bug report
diff --git a/doc/bugs/osm_plugin_fails_to_display_map_with_javascript_error.mdwn b/doc/bugs/osm_plugin_fails_to_display_map_with_javascript_error.mdwn
new file mode 100644
index 0000000..bc92e80
--- /dev/null
+++ b/doc/bugs/osm_plugin_fails_to_display_map_with_javascript_error.mdwn
@@ -0,0 +1,12 @@
+A simple use of this plugin seems to fail now,
+yeilding either a blank map or some javascript errors.
+
+The javascript errors I saw are:
+
+	SyntaxError: syntax error
+	OpenLayers.js (line 476, col 64)
+
+	ReferenceError: OpenLayers is not defined
+	osm.js (line 30, col 1)
+
+--[[Joey]]

add more details of CVE-2015-2793
diff --git a/doc/security.mdwn b/doc/security.mdwn
index 6488d7f..d5a0266 100644
--- a/doc/security.mdwn
+++ b/doc/security.mdwn
@@ -500,9 +500,9 @@ as version 3.20100815.9. An upgrade is recommended for all sites.
 
 ## XSS via openid selector
 
-Raghav Bisht discovered this XSS in the openid selector.
+Raghav Bisht discovered this XSS in the openid selector. ([[!cve CVE-2015-2793]])
 
 The hole was reported on March 24th, a fix was developed on March 27th,
-and the fixed version was released on the 29th. A fix was backported
-to Debian wheezy as version 3.20141016.2. An upgrade is recommended for
-sites using CGI and openid.
+and the fixed version 3.20150329 was released on the 29th. A fix was backported
+to Debian jessie as version 3.20141016.2 and to Debian wheezy as version
+3.20120629.2. An upgrade is recommended for sites using CGI and openid.

yes Debian wheezy is vulnerable, a proposed-update is queued
diff --git a/doc/bugs/XSS_Alert...__33____33____33__.mdwn b/doc/bugs/XSS_Alert...__33____33____33__.mdwn
index c44ab09..cb96187 100644
--- a/doc/bugs/XSS_Alert...__33____33____33__.mdwn
+++ b/doc/bugs/XSS_Alert...__33____33____33__.mdwn
@@ -41,3 +41,13 @@ raghav007bisht@gmail.com
 
 > Are versions `3.20120629` or `3.20130904.1~bpo70+1` vulnerable? (`wheezy` and
 > `wheezy-backports`, respectively) — [[Jon]]
+
+>> 3.20120629 is vulnerable; fixed in 3.20120629.2, which is in the proposed-updates
+>> queue (the security team declined to issue a DSA). The blogspam plugin doesn't
+>> work in wheezy either; again, a fix is in the proposed-updates queue.
+>>
+>> 3.20130904.1~bpo70+1 is almost certainly vulnerable, it looks as though someone
+>> has done a drive-by backport but not kept it updated. None of ikiwiki's Debian
+>> maintainers are involved in that backport; the .deb from jessie (or even from
+>> experimental) works fine on wheezy without recompilation. I use the latest
+>> upstream release from experimental on my otherwise-Debian-7 server. --[[smcv]]

is ikiwiki in wheezy vulnerable?
diff --git a/doc/bugs/XSS_Alert...__33____33____33__.mdwn b/doc/bugs/XSS_Alert...__33____33____33__.mdwn
index d103610..c44ab09 100644
--- a/doc/bugs/XSS_Alert...__33____33____33__.mdwn
+++ b/doc/bugs/XSS_Alert...__33____33____33__.mdwn
@@ -38,3 +38,6 @@ raghav007bisht@gmail.com
 >> until the maintainer can respond ("[[!wikipedia responsible disclosure]]").
 >> In this particular case, I was away from my computer for a few days
 >> and was unable to make a release until I got back. --[[smcv]]
+
+> Are versions `3.20120629` or `3.20130904.1~bpo70+1` vulnerable? (`wheezy` and
+> `wheezy-backports`, respectively) — [[Jon]]

Added a comment
diff --git a/doc/forum/zombie-ish___34__org.com__34___email_address/comment_2_33d9c1917a50a84abc0966a96a9db9a7._comment b/doc/forum/zombie-ish___34__org.com__34___email_address/comment_2_33d9c1917a50a84abc0966a96a9db9a7._comment
new file mode 100644
index 0000000..fe6d23b
--- /dev/null
+++ b/doc/forum/zombie-ish___34__org.com__34___email_address/comment_2_33d9c1917a50a84abc0966a96a9db9a7._comment
@@ -0,0 +1,14 @@
+[[!comment format=mdwn
+ username="smcv"
+ subject="comment 2"
+ date="2015-04-13T17:29:50Z"
+ content="""
+If you are logging in using [[plugins/passwordauth]] or [[plugins/httpauth]],
+your email address as used in Preferences is your choice, and you should be
+able to change it via Preferences.
+
+If you are logging in using OpenID, your email address as used in Preferences comes
+from your OpenID provider.
+
+Either way, it's stored in [[the userdb|tips/inside_dot_ikiwiki]].
+"""]]

osm
diff --git a/doc/sandbox.mdwn b/doc/sandbox.mdwn
index e4887be..3f61d29 100644
--- a/doc/sandbox.mdwn
+++ b/doc/sandbox.mdwn
@@ -1,3 +1,7 @@
+[[!osm ]]
+[[!waypoint  lat="45°30N" lon="73°40W" name="My city" tag="city"]]
+
+
 [[!meta date="Thu Jun 16 22:04:33 2005" updated="Thu Dec 22 01:23:20 2011"]]
 
 This is the [[SandBox]], a page anyone can edit to try out ikiwiki

diff --git a/doc/forum/zombie-ish___34__org.com__34___email_address.mdwn b/doc/forum/zombie-ish___34__org.com__34___email_address.mdwn
index 1a9eac8..94eda9b 100644
--- a/doc/forum/zombie-ish___34__org.com__34___email_address.mdwn
+++ b/doc/forum/zombie-ish___34__org.com__34___email_address.mdwn
@@ -4,6 +4,9 @@ The actual address -- as is on clear display in the wiki's setup file -- is of t
 
 I have done 'ikiwiki --rebuild --setup mywikis.setup' to no avail. I have grepped everywhere I can think of looking for "org.com." Also no joy.
 
+
 Signed,
 
 Mystified in Rhode Island!
+
+[wingnut@zeus.jtan.com](mailto: wingnut@zeus.jtan.com)

Added a comment: zombie
diff --git a/doc/forum/zombie-ish___34__org.com__34___email_address/comment_1_82efeb21505a92b380b2ba9087b80e68._comment b/doc/forum/zombie-ish___34__org.com__34___email_address/comment_1_82efeb21505a92b380b2ba9087b80e68._comment
new file mode 100644
index 0000000..2154146
--- /dev/null
+++ b/doc/forum/zombie-ish___34__org.com__34___email_address/comment_1_82efeb21505a92b380b2ba9087b80e68._comment
@@ -0,0 +1,8 @@
+[[!comment format=mdwn
+ username="https://me.yahoo.com/a/eetjWe8B34ZeUsHyFzpwC5QvBcEuVxllSvpJHw--#376d7"
+ nickname="Bob"
+ subject="zombie"
+ date="2015-04-07T19:00:48Z"
+ content="""
+I forgot to note that the bogus email addy (*.org.com) appears in the \"Preferecnes\" screen. Nowhere else.
+"""]]

diff --git a/doc/forum/zombie-ish___34__org.com__34___email_address.mdwn b/doc/forum/zombie-ish___34__org.com__34___email_address.mdwn
new file mode 100644
index 0000000..1a9eac8
--- /dev/null
+++ b/doc/forum/zombie-ish___34__org.com__34___email_address.mdwn
@@ -0,0 +1,9 @@
+I have a bogus admin email address infesting a new wiki. 
+
+The actual address -- as is on clear display in the wiki's setup file -- is of the form "bob@bobsdomain.org". The infestation, which I cannot kill, or so it seems, is of the form "bob@bobsdomain.org.com".
+
+I have done 'ikiwiki --rebuild --setup mywikis.setup' to no avail. I have grepped everywhere I can think of looking for "org.com." Also no joy.
+
+Signed,
+
+Mystified in Rhode Island!

Update comment on bug
diff --git a/doc/bugs/wrong_rendering_of_templatebody.mdwn b/doc/bugs/wrong_rendering_of_templatebody.mdwn
index 6b77501..20d9060 100644
--- a/doc/bugs/wrong_rendering_of_templatebody.mdwn
+++ b/doc/bugs/wrong_rendering_of_templatebody.mdwn
@@ -50,6 +50,10 @@ page gets rebuilt automatically after some git push, it renders the wrong way.
 >> the git push output, because rendering the wiki from command line doesn't have this
 >> problem.
 >>
+>> One more thing, my setup uses the pingee plugin. When doing a git push, it browses to
+>> the wiki page using wget with `?do=ping` parameter, and then ikiwiki responds by rebuilding
+>> the necessary pages.
+>>
 >> Thanks for the pointers.
 >>
 >> --[[fr33domlover]]

Comment on templatebody bug
diff --git a/doc/bugs/wrong_rendering_of_templatebody.mdwn b/doc/bugs/wrong_rendering_of_templatebody.mdwn
index 51cf58a..6b77501 100644
--- a/doc/bugs/wrong_rendering_of_templatebody.mdwn
+++ b/doc/bugs/wrong_rendering_of_templatebody.mdwn
@@ -51,6 +51,9 @@ page gets rebuilt automatically after some git push, it renders the wrong way.
 >> problem.
 >>
 >> Thanks for the pointers.
+>>
+>> --[[fr33domlover]]
+
 
 [[This|http://www.rel4tion.org/languages/haskell/]] is the page, and
 [[this|http://www.rel4tion.org/templates/wikitag/]] is a template it uses. Right

Comment on templatebody bug
diff --git a/doc/bugs/wrong_rendering_of_templatebody.mdwn b/doc/bugs/wrong_rendering_of_templatebody.mdwn
index c4c04be..51cf58a 100644
--- a/doc/bugs/wrong_rendering_of_templatebody.mdwn
+++ b/doc/bugs/wrong_rendering_of_templatebody.mdwn
@@ -35,6 +35,23 @@ page gets rebuilt automatically after some git push, it renders the wrong way.
 > early stage - I would suggest `getsetup()`, `refresh()` and `import()`
 > respectively. --[[smcv]]
 
+>> Yes, I installed in `/usr/local`, but I also removed the deb package. So I
+>> only have 1 ikiwiki version now.
+>>
+>> I also noticed the following behavior. I created a set of pages, each of them
+>> containing several occurences of a certain template. Then I created another
+>> page, which inlines all of them. All good. Then, I edited that main page to do
+>> different sorting (using inline directive's sort option). After comitting the change,
+>> suddenly all the inlined pages have the templates inside them contain the
+>> template info instead of template body. How is that even related to the minor
+>> change I did - change the sorting? :-P
+>>
+>> I'll look at the templatebody.pm file and try debug prints. I hope I can see them in
+>> the git push output, because rendering the wiki from command line doesn't have this
+>> problem.
+>>
+>> Thanks for the pointers.
+
 [[This|http://www.rel4tion.org/languages/haskell/]] is the page, and
 [[this|http://www.rel4tion.org/templates/wikitag/]] is a template it uses. Right
 now the template is rendered on that page exactly like the template page itself.

diff --git a/doc/sandbox.mdwn b/doc/sandbox.mdwn
index e620dd3..e4887be 100644
--- a/doc/sandbox.mdwn
+++ b/doc/sandbox.mdwn
@@ -66,6 +66,7 @@ Bulleted list
 > a blockquote
 > in a list
 > how is this handled
+        *this  _ _ _
       * this 2
       * this 3
 

diff --git a/doc/sandbox.mdwn b/doc/sandbox.mdwn
index 0c581bf..e620dd3 100644
--- a/doc/sandbox.mdwn
+++ b/doc/sandbox.mdwn
@@ -63,6 +63,9 @@ Bulleted list
   * and more
     * and
       * this
+> a blockquote
+> in a list
+> how is this handled
       * this 2
       * this 3
 

diff --git a/doc/sandbox.mdwn b/doc/sandbox.mdwn
index 2331caf..0c581bf 100644
--- a/doc/sandbox.mdwn
+++ b/doc/sandbox.mdwn
@@ -56,6 +56,15 @@ Bulleted list
 * one
   * footballs; runner; unices
   * Cool !
+    * test
+  * this
+* something else
+  * some more
+  * and more
+    * and
+      * this
+      * this 2
+      * this 3
 
 test _this_ out.
 

Typos
diff --git a/doc/ikiwiki/directive/meta/discussion.mdwn b/doc/ikiwiki/directive/meta/discussion.mdwn
index c0efffd..5461d2e 100644
--- a/doc/ikiwiki/directive/meta/discussion.mdwn
+++ b/doc/ikiwiki/directive/meta/discussion.mdwn
@@ -81,4 +81,4 @@ Also, being able to use the language variable in templates would be very useful
 
 ----
 
-When `title` is set, is there a way to get the real `pagename` in templates (so that I can use `title_overridden` to render the pagename, as the last of the URL, in a breadcrumb-like part) ? -- [[BBB]]
+When `title` is set, is there a way to get the real `pagename` in templates (so that I can use `title_overridden` to render the pagename, as the last part of the page URL, in breadcrumbs) ? -- [[BBB]]

Add question about meta, title and pagename
diff --git a/doc/ikiwiki/directive/meta/discussion.mdwn b/doc/ikiwiki/directive/meta/discussion.mdwn
index 428f454..c0efffd 100644
--- a/doc/ikiwiki/directive/meta/discussion.mdwn
+++ b/doc/ikiwiki/directive/meta/discussion.mdwn
@@ -78,3 +78,7 @@ I guess patching [[/ikiwiki/directive/meta]] to document the fact this attribute
 The problem is that it does not generate the lang attribute in `<html>` and that's what's required for [hyphenation](https://developer.mozilla.org/en-US/docs/Web/CSS/hyphens) so this would be welcome too!
 
 Also, being able to use the language variable in templates would be very useful for various css tweaks. — [Hugo](https://hroy.eu)
+
+----
+
+When `title` is set, is there a way to get the real `pagename` in templates (so that I can use `title_overridden` to render the pagename, as the last of the URL, in a breadcrumb-like part) ? -- [[BBB]]

had a 500 here
diff --git a/doc/bugs/ikiwiki_explodes_when_git_rewrites_history.mdwn b/doc/bugs/ikiwiki_explodes_when_git_rewrites_history.mdwn
index 0e67bfb..fa83992 100644
--- a/doc/bugs/ikiwiki_explodes_when_git_rewrites_history.mdwn
+++ b/doc/bugs/ikiwiki_explodes_when_git_rewrites_history.mdwn
@@ -15,3 +15,5 @@ Notice how the error message from git isn't present. It's in the `error.log`:
 </pre>
 
 The workaround I have found was to remove the `indexdb` file, because that's [[apparently legit|tips/inside_dot_ikiwiki/]]. But it would be nice to have (1) a proper error message (it had to dig around the error.log to understand what's going on), (2) to have a proper fallback if the `git log` fails and (3) to recover with the newer commit ID when we fallback. --[[anarcat]]
+
+> FWIW, I had a `500 Internal Server Error` while submitting this bug at first. :)

small bug
diff --git a/doc/bugs/ikiwiki_explodes_when_git_rewrites_history.mdwn b/doc/bugs/ikiwiki_explodes_when_git_rewrites_history.mdwn
new file mode 100644
index 0000000..0e67bfb
--- /dev/null
+++ b/doc/bugs/ikiwiki_explodes_when_git_rewrites_history.mdwn
@@ -0,0 +1,17 @@
+Now I know it's "bad" to rewrite history in git, but sometimes, and especially with public sites such as a wiki, if confidential information gets transmitted in the wiki, it can be pretty important to remove it, and the only way to do this on a public git repo is by rewriting history.
+
+(This happened as part of my implementation of [[todo/git-annex support]] to be honest, but i think it applies to other situations as well.)
+
+The problem is that ikiwiki keeps track of the last commit it saw in `$srcdir/.ikiwiki/indexdb`. Then it uses this to infer which files changed. If history changed, this will fail with a fairly dramatic:
+
+<pre>
+Error: 'git log --pretty=raw --raw --abbrev=40 --always -c --no-renames --reverse -r f9330f40527ba1f7df6656490cacb9d5ae9e2cd6..HEAD -- .' failed:
+</pre>
+
+Notice how the error message from git isn't present. It's in the `error.log`:
+
+<pre>
+[Mon Mar 30 20:20:04.393466 2015] [cgi:error] [pid 21463] [client 2001:1928:1:9::1:54315] AH01215: fatal: Invalid revision range f9330f40527ba1f7df6656490cacb9d5ae9e2cd6, referer: http://anarc.at/ikiwiki.cgi?do=edit&page=services%2Fwiki
+</pre>
+
+The workaround I have found was to remove the `indexdb` file, because that's [[apparently legit|tips/inside_dot_ikiwiki/]]. But it would be nice to have (1) a proper error message (it had to dig around the error.log to understand what's going on), (2) to have a proper fallback if the `git log` fails and (3) to recover with the newer commit ID when we fallback. --[[anarcat]]

security review seems to say this is an okay change
diff --git a/doc/todo/git-annex_support.mdwn b/doc/todo/git-annex_support.mdwn
index a0b0a71..5e0a363 100644
--- a/doc/todo/git-annex_support.mdwn
+++ b/doc/todo/git-annex_support.mdwn
@@ -178,7 +178,20 @@ index 9d6f636..e0b4cf8 100644
                                         push @IkiWiki::underlayfiles, $f;
 </pre>
 
-Now obviously this patch is incomplete: I am not sure we actually avoid the attack, ie. i am not sure the check in `srcdir()` is sufficient to remove completely the check in `find_src_files()`. It does work, however: the files get picked up from the underlay and properly hardlinked into the target `public_html` directory! So with the above patch, then the following hook in `source.git/hooks/post-receive`:
+<del>Now obviously this patch is incomplete: I am not sure we actually avoid the attack, ie. i am not sure the check in `srcdir()` is sufficient to remove completely the check in `find_src_files()`.</del>
+
+After reviewing the code further, it seems that `find_src_files` in three places in ikiwiki:
+
+<pre>
+../IkiWiki/Render.pm:421:	find_src_files(1, \@files, \%pages);
+../IkiWiki/Render.pm:846:		($files, $pages)=find_src_files();
+../po/po2wiki:18:my ($files, $pages)=IkiWiki::find_src_files();
+</pre>
+
+The first occurence is in `IkiWiki::Render::process_changed_files`, where it is used mostly for populating `@IkiWiki::underlayfiles`, the only side effect of 
+`find_src_files`. The second occurence is in `IkiWiki::Render::refresh`. There things are a little more complicated (to say the least) and a lot of stuff happens. To put it in broad terms, first it does a `IkiWiki::Render::scan` and then a `IkiWiki::Render::render`. The last two call `srcfile()` appropriately (where i put an extra symlink check), except for  `will_render()` in `scan`, which I can't figure out right now and that seems to have a lot of global side effects. It still looks fairly safe at first glance. The `rcs_get_current_rev`, `refresh`, `scan` and `rendered` hooks are also called in there, but I assume those to be safe, since they are called with sanitized values already.
+
+The patch does work: the files get picked up from the underlay and properly hardlinked into the target `public_html` directory! So with the above patch, then the following hook in `source.git/hooks/post-receive`:
 
 <pre>
 #!/bin/sh

update for recent XSS
diff --git a/doc/security.mdwn b/doc/security.mdwn
index afefd1b..6488d7f 100644
--- a/doc/security.mdwn
+++ b/doc/security.mdwn
@@ -497,3 +497,12 @@ Raúl Benencia discovered an additional XSS exposure in the meta plugin.
 This hole was discovered on 16 May 2012 and fixed the same day with
 the release of ikiwiki 3.20120516. A fix was backported to Debian squeeze,
 as version 3.20100815.9. An upgrade is recommended for all sites.
+
+## XSS via openid selector
+
+Raghav Bisht discovered this XSS in the openid selector.
+
+The hole was reported on March 24th, a fix was developed on March 27th,
+and the fixed version was released on the 29th. A fix was backported
+to Debian wheezy as version 3.20141016.2. An upgrade is recommended for
+sites using CGI and openid.

respond
diff --git a/doc/bugs/Commonmark_support.mdwn b/doc/bugs/Commonmark_support.mdwn
index 5ee014b..b05f67f 100644
--- a/doc/bugs/Commonmark_support.mdwn
+++ b/doc/bugs/Commonmark_support.mdwn
@@ -1,3 +1,20 @@
 I suffer from the occasional markdown glitches using branchable.
 
 I've found that switching my own non-ikiwiki projects to https://github.com/jgm/CommonMark has helped sort them out for the most part.
+
+> ikiwiki does not implement Markdown on its own: it uses one of several
+> third-party libraries, with the current recommendation being
+> Discount. Out-of-process implementations like
+> [[plugins/contrib/pandoc]] are not suitable to be the default for
+> performance reasons.
+>
+> There seems to be a Perl binding for libcmark at
+> <https://github.com/nwellnhof/perl-commonmark>, but unfortunately
+> its README points out that the libcmark API is not stable,
+> which means libcmark and perl-commonmark would have to be upgraded
+> in lockstep: this makes them awkward to deal with in Linux
+> distributions. As a result I'm not going to look into this myself
+> until there is a stable API for Commonmark available in Debian.
+>
+> However, if you want to add optional Commonmark support to the
+> [[plugins/mdwn]] plugin, I'd review a patch. --[[smcv]]

close fixed bug
diff --git a/doc/bugs/XSS_Alert...__33____33____33__.mdwn b/doc/bugs/XSS_Alert...__33____33____33__.mdwn
index 2c14707..d103610 100644
--- a/doc/bugs/XSS_Alert...__33____33____33__.mdwn
+++ b/doc/bugs/XSS_Alert...__33____33____33__.mdwn
@@ -29,3 +29,12 @@ raghav007bisht@gmail.com
 > Thanks Raghav for reporting this issue. I've fixed it in ikiwiki.
 > 
 > --[[Joey]] 
+
+>> [[Fix released|done]] as [[news/version_3.20150329]].
+>>
+>> Please try to report security vulnerabilities in private first,
+>> to give maintainers a chance to fix them without making it easier
+>> for attackers to exploit the newly discovered vulnerability
+>> until the maintainer can respond ("[[!wikipedia responsible disclosure]]").
+>> In this particular case, I was away from my computer for a few days
+>> and was unable to make a release until I got back. --[[smcv]]

fix formatting
diff --git a/doc/bugs/XSS_Alert...__33____33____33__.mdwn b/doc/bugs/XSS_Alert...__33____33____33__.mdwn
index 436e3fa..2c14707 100644
--- a/doc/bugs/XSS_Alert...__33____33____33__.mdwn
+++ b/doc/bugs/XSS_Alert...__33____33____33__.mdwn
@@ -5,14 +5,16 @@ Vulnerable Links:
 webconverger.org/ikiwiki.cgi?action=verify&do=signin&openid_identifier=1
 
 How To Reproduce The Vulnerability :
+
 1. Go to this link : webconverger.org/ikiwiki.cgi?action=verify&do=signin&openid_identifier=1
 2. refresh the page and intercept the http request using "brup suite" then at parameter "openid_identifier=" put xss payload
 3. forward the request
 
 XSS Payload :
-1. "></script><script>prompt(909043)</script>
-2. "></script><script>prompt("XSS Alert...!!! : Hacked By Raghav Bisht")</script>
-3. "></script><script>prompt(document.cookie)</script>
+
+1. `"></script><script>prompt(909043)</script>`
+2. `"></script><script>prompt("XSS Alert...!!! : Hacked By Raghav Bisht")</script>`
+3. `"></script><script>prompt(document.cookie)</script>`
 
 NOTE : Proof of concept is attached.
 

rename bugs/XSS_Alert...__33____33____33__.html to bugs/XSS_Alert...__33____33____33__.mdwn
diff --git a/doc/bugs/XSS_Alert...__33____33____33__.html b/doc/bugs/XSS_Alert...__33____33____33__.html
deleted file mode 100644
index 436e3fa..0000000
--- a/doc/bugs/XSS_Alert...__33____33____33__.html
+++ /dev/null
@@ -1,29 +0,0 @@
-Respected Sir,
-Your website "webconverger.org" is vulnerable to XSS Attack.
-
-Vulnerable Links:
-webconverger.org/ikiwiki.cgi?action=verify&do=signin&openid_identifier=1
-
-How To Reproduce The Vulnerability :
-1. Go to this link : webconverger.org/ikiwiki.cgi?action=verify&do=signin&openid_identifier=1
-2. refresh the page and intercept the http request using "brup suite" then at parameter "openid_identifier=" put xss payload
-3. forward the request
-
-XSS Payload :
-1. "></script><script>prompt(909043)</script>
-2. "></script><script>prompt("XSS Alert...!!! : Hacked By Raghav Bisht")</script>
-3. "></script><script>prompt(document.cookie)</script>
-
-NOTE : Proof of concept is attached.
-
-
-Thank You...!!
-
-
-Your Faithfully,
-Raghav Bisht
-raghav007bisht@gmail.com
-
-> Thanks Raghav for reporting this issue. I've fixed it in ikiwiki.
-> 
-> --[[Joey]] 
diff --git a/doc/bugs/XSS_Alert...__33____33____33__.mdwn b/doc/bugs/XSS_Alert...__33____33____33__.mdwn
new file mode 100644
index 0000000..436e3fa
--- /dev/null
+++ b/doc/bugs/XSS_Alert...__33____33____33__.mdwn
@@ -0,0 +1,29 @@
+Respected Sir,
+Your website "webconverger.org" is vulnerable to XSS Attack.
+
+Vulnerable Links:
+webconverger.org/ikiwiki.cgi?action=verify&do=signin&openid_identifier=1
+
+How To Reproduce The Vulnerability :
+1. Go to this link : webconverger.org/ikiwiki.cgi?action=verify&do=signin&openid_identifier=1
+2. refresh the page and intercept the http request using "brup suite" then at parameter "openid_identifier=" put xss payload
+3. forward the request
+
+XSS Payload :
+1. "></script><script>prompt(909043)</script>
+2. "></script><script>prompt("XSS Alert...!!! : Hacked By Raghav Bisht")</script>
+3. "></script><script>prompt(document.cookie)</script>
+
+NOTE : Proof of concept is attached.
+
+
+Thank You...!!
+
+
+Your Faithfully,
+Raghav Bisht
+raghav007bisht@gmail.com
+
+> Thanks Raghav for reporting this issue. I've fixed it in ikiwiki.
+> 
+> --[[Joey]] 

also mention 3.20141016.2
diff --git a/doc/news/version_3.20150329.mdwn b/doc/news/version_3.20150329.mdwn
index 0ac19a8..983bd2e 100644
--- a/doc/news/version_3.20150329.mdwn
+++ b/doc/news/version_3.20150329.mdwn
@@ -1,4 +1,6 @@
-ikiwiki 3.20150329 released with [[!toggle text="these changes"]]
+ikiwiki 3.20150329 released with [[!toggle text="these changes"]]. This is a
+security update fixing a cross-site scripting vulnerability.
+
 [[!toggleable text="""
   [ [[Joey Hess|joey]] ]
 
@@ -25,3 +27,6 @@ ikiwiki 3.20150329 released with [[!toggle text="these changes"]]
   * Fix XSS in openid selector. Thanks, Raghav Bisht.
     (Closes: [[!debbug 781483]])
 """]]
+
+In addition, version 3.20141016.2 was released on the same day to backport
+the cross-site-scripting fix to Debian 8.

fix formatting
diff --git a/doc/news/version_3.20150329.mdwn b/doc/news/version_3.20150329.mdwn
index 787efd9..0ac19a8 100644
--- a/doc/news/version_3.20150329.mdwn
+++ b/doc/news/version_3.20150329.mdwn
@@ -1,9 +1,11 @@
 ikiwiki 3.20150329 released with [[!toggle text="these changes"]]
 [[!toggleable text="""
   [ [[Joey Hess|joey]] ]
+
   * Fix NULL ptr deref on ENOMEM in wrapper. (Thanks, igli)
 
   [ [[Simon McVittie|smcv]] ]
+
   * Really don't double-decode CGI submissions, even on Perl versions that
     bundle an old enough Encode.pm for that not to be a problem: the
     system might have a newer Encode.pm installed separately, like Fedora 20.
@@ -15,9 +17,11 @@ ikiwiki 3.20150329 released with [[!toggle text="these changes"]]
   * Consistently document command-line options as e.g. --refresh, not -refresh
 
   [ [[Amitai Schlair|schmonz]] ]
+
   * In VCS-committed anonymous comments, link to url.
 
   [ [[Joey Hess|joey]] ]
+
   * Fix XSS in openid selector. Thanks, Raghav Bisht.
     (Closes: [[!debbug 781483]])
 """]]

Add news for version 3.20150329
diff --git a/doc/news/version_3.20150329.mdwn b/doc/news/version_3.20150329.mdwn
new file mode 100644
index 0000000..787efd9
--- /dev/null
+++ b/doc/news/version_3.20150329.mdwn
@@ -0,0 +1,23 @@
+ikiwiki 3.20150329 released with [[!toggle text="these changes"]]
+[[!toggleable text="""
+  [ [[Joey Hess|joey]] ]
+  * Fix NULL ptr deref on ENOMEM in wrapper. (Thanks, igli)
+
+  [ [[Simon McVittie|smcv]] ]
+  * Really don't double-decode CGI submissions, even on Perl versions that
+    bundle an old enough Encode.pm for that not to be a problem: the
+    system might have a newer Encode.pm installed separately, like Fedora 20.
+    (Closes: [[!debbug 776181]]; thanks, Anders Kaseorg)
+  * If neither timezone nor TZ is set, set both to :/etc/localtime if
+    we're on a GNU system and that file exists, or GMT otherwise
+  * t/inline.t: accept translations of "Add a new post titled:"
+    (Closes: [[!debbug 779365]])
+  * Consistently document command-line options as e.g. --refresh, not -refresh
+
+  [ [[Amitai Schlair|schmonz]] ]
+  * In VCS-committed anonymous comments, link to url.
+
+  [ [[Joey Hess|joey]] ]
+  * Fix XSS in openid selector. Thanks, Raghav Bisht.
+    (Closes: [[!debbug 781483]])
+"""]]

ouf, works!
diff --git a/doc/todo/git-annex_support.mdwn b/doc/todo/git-annex_support.mdwn
index 3c0b228..a0b0a71 100644
--- a/doc/todo/git-annex_support.mdwn
+++ b/doc/todo/git-annex_support.mdwn
@@ -213,4 +213,4 @@ add_underlays:
 
 ... and the `ikiwiki-hosting` patch mentionned earlier to allow git-annex-shell to run at all. Also, the `--shared` option will [make git-annex use hardlinks itself between the two repos](https://git-annex.branchable.com/todo/wishlist:_use_hardlinks_for_local_clones/), so the files will be available for download as well. --[[anarcat]]
 
-> ...aaaand this doesn't work anymore. :( i could have sworn this was working minutes ago, but for some reason the annexed files get skipped again now. :( --[[anarcat]]
+> <del>...aaaand this doesn't work anymore. :( i could have sworn this was working minutes ago, but for some reason the annexed files get skipped again now. :(</del> Sorry for the noise, the annex repo wasn't in direct mode - the above works! --[[anarcat]]

fail
diff --git a/doc/todo/git-annex_support.mdwn b/doc/todo/git-annex_support.mdwn
index 7662aeb..3c0b228 100644
--- a/doc/todo/git-annex_support.mdwn
+++ b/doc/todo/git-annex_support.mdwn
@@ -212,3 +212,5 @@ add_underlays:
 </pre>
 
 ... and the `ikiwiki-hosting` patch mentionned earlier to allow git-annex-shell to run at all. Also, the `--shared` option will [make git-annex use hardlinks itself between the two repos](https://git-annex.branchable.com/todo/wishlist:_use_hardlinks_for_local_clones/), so the files will be available for download as well. --[[anarcat]]
+
+> ...aaaand this doesn't work anymore. :( i could have sworn this was working minutes ago, but for some reason the annexed files get skipped again now. :( --[[anarcat]]

diff --git a/doc/tips/Ikiwiki_with_git-annex__44___the_album_and_the_underlay_plugins/discussion.mdwn b/doc/tips/Ikiwiki_with_git-annex__44___the_album_and_the_underlay_plugins/discussion.mdwn
new file mode 100644
index 0000000..f698439
--- /dev/null
+++ b/doc/tips/Ikiwiki_with_git-annex__44___the_album_and_the_underlay_plugins/discussion.mdwn
@@ -0,0 +1 @@
+i don't understand how this works, but I think i made it work "the right way"(TM) in [[todo/git-annex_support]] now... please review and feedback! --[[anarcat]]

Added a comment: progress
diff --git a/doc/forum/ikiwiki_and_big_files/comment_6_3c1c73c9f7e6e8fad81957eeda7124d4._comment b/doc/forum/ikiwiki_and_big_files/comment_6_3c1c73c9f7e6e8fad81957eeda7124d4._comment
new file mode 100644
index 0000000..619d116
--- /dev/null
+++ b/doc/forum/ikiwiki_and_big_files/comment_6_3c1c73c9f7e6e8fad81957eeda7124d4._comment
@@ -0,0 +1,7 @@
+[[!comment format=mdwn
+ username="https://id.koumbit.net/anarcat"
+ subject="progress"
+ date="2015-03-28T16:31:52Z"
+ content="""
+i made some progress here, please review and test suggested changes in [[todo/git-annex_support]]. --[[anarcat]]
+"""]]

figure it out at last: would need review from smcv for symlink security
diff --git a/doc/todo/git-annex_support.mdwn b/doc/todo/git-annex_support.mdwn
index afec8c6..7662aeb 100644
--- a/doc/todo/git-annex_support.mdwn
+++ b/doc/todo/git-annex_support.mdwn
@@ -135,3 +135,80 @@ git annex move --to annex
 I have added this as a hook in `$HOME/source.git/hooks/post-receive` (don't forget to `chmod +x`).
 
 The problem with the above is that the underlay wouldn't work: for some reason it wouldn't copy those files in place properly. Maybe it's freaking out because it's a full copy of the repo... My solution was to make the source repository itself a direct repo, and then add it as a remote to the bare repo. --[[anarcat]]
+
+Back from the top
+=================
+
+Obviously, the final approach of making the `source` repository direct mode will fail because ikiwiki will try to commit files there from the web interface which will fail (at best) and (at worst) add big files into git-annex (or vice-versa, not sure what's worse actually).
+
+Also, I don't know how others here made the underlay work, but it didn't work for me. I think it's because in the "source" repository, there are (dead) symlinks for the annexed files. This overrides the underlay, because of [[security]] - although I am unclear as to why this is discarded so early. So in order to make the original idea above work properly (ie. having a separate git-annex repo in direct mode) work, we must coerce ikiwiki into tolerating symlinks in the srcdir a little more:
+
+<pre>
+diff --git a/IkiWiki.pm b/IkiWiki.pm
+index 1043ef4..949273c 100644
+--- a/IkiWiki.pm
++++ b/IkiWiki.pm
+@@ -916,11 +916,10 @@ sub srcfile_stat {
+        my $file=shift;
+        my $nothrow=shift;
+
+-       return "$config{srcdir}/$file", stat(_) if -e "$config{srcdir}/$file";
+-       foreach my $dir (@{$config{underlaydirs}}, $config{underlaydir}) {
+-               return "$dir/$file", stat(_) if -e "$dir/$file";
++       foreach my $dir ($config{srcdir}, @{$config{underlaydirs}}, $config{underlaydir}) {
++               return "$dir/$file", stat(_) if (-e "$dir/$file" && ! -l "$dir/$file");
+        }
+-       error("internal error: $file cannot be found in $config{srcdir} or underlay") unless $nothrow;
++       error("internal error: $file cannot be found in $config{srcdir} or underlays @{$config{underlaydirs}} $config{underlaydir}") unless $nothrow;
+        return;
+ }
+
+diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm
+index 9d6f636..e0b4cf8 100644
+--- a/IkiWiki/Render.pm
++++ b/IkiWiki/Render.pm
+@@ -337,7 +337,7 @@ sub find_src_files (;$$$) {
+
+                if ($underlay) {
+                        # avoid underlaydir override attacks; see security.mdwn
+-                       if (! -l "$abssrcdir/$f" && ! -e _) {
++                       if (1 || ! -l "$abssrcdir/$f" && ! -e _) {
+                                if (! $pages{$page}) {
+                                        push @files, $f;
+                                        push @IkiWiki::underlayfiles, $f;
+</pre>
+
+Now obviously this patch is incomplete: I am not sure we actually avoid the attack, ie. i am not sure the check in `srcdir()` is sufficient to remove completely the check in `find_src_files()`. It does work, however: the files get picked up from the underlay and properly hardlinked into the target `public_html` directory! So with the above patch, then the following hook in `source.git/hooks/post-receive`:
+
+<pre>
+#!/bin/sh
+
+OLD_GIT_DIR="$GIT_DIR"
+unset GIT_DIR
+echo "moving big files to annex repository..."
+git annex copy --to annex
+git annex sync annex
+</pre>
+
+(I am not sure anymore why GIT_DIR is necessary, but I remember it destroyed all files in my repo because git-annex synced against the `setup` branch in the parent directory. fun times.)
+
+Then the `annex` repo is just a direct clone of the source.git:
+
+<pre>
+cd /home/user
+git clone --shared source.git annex
+cd annex
+git annex direct
+cd ../source.git
+git remote add annex ../annex
+</pre>
+
+And we need the following config:
+
+<pre>
+hardlink: 1
+add_underlays:
+- /home/w-anarcat/annex
+</pre>
+
+... and the `ikiwiki-hosting` patch mentionned earlier to allow git-annex-shell to run at all. Also, the `--shared` option will [make git-annex use hardlinks itself between the two repos](https://git-annex.branchable.com/todo/wishlist:_use_hardlinks_for_local_clones/), so the files will be available for download as well. --[[anarcat]]

another attempt
diff --git a/doc/todo/git-annex_support.mdwn b/doc/todo/git-annex_support.mdwn
index 7821962..afec8c6 100644
--- a/doc/todo/git-annex_support.mdwn
+++ b/doc/todo/git-annex_support.mdwn
@@ -101,3 +101,37 @@ An alternative implementation, which remains to be detailed but is mentionned in
 Also note that ikiwiki-hosting has a [patch waiting](https://ikiwiki-hosting.branchable.com/todo/git-annex_support) to allow pushes to work with git-annex. This could potentially be expanded to sync content to the final checkout properly, avoiding some of the problems above (esp. wrt to non-annex bare repos).
 
 Combined with the [[underlay]] feature, this could work very nicely indeed... --[[anarcat]]
+
+Here's an attempt:
+
+<pre>
+cd /home/user
+git clone source.git source.annex
+cd source.annex
+git annex direct
+cd ../source.git
+git annex group . transfer
+git remote add annex ../source.annex
+git annex sync annex
+</pre>
+
+Make sure the `hardlink` setting is enabled, and add the annex as an underlay, in `ikiwiki.setup`:
+
+<pre>
+hardlink: 1
+add_underlays:
+- /home/w-anarcat/source.annex
+</pre>
+
+Then moving files to the underlay is as simple as running this command in the bare repo:
+
+<pre>
+#!/bin/sh
+
+echo "moving big files to annex repository..."
+git annex move --to annex
+</pre>
+
+I have added this as a hook in `$HOME/source.git/hooks/post-receive` (don't forget to `chmod +x`).
+
+The problem with the above is that the underlay wouldn't work: for some reason it wouldn't copy those files in place properly. Maybe it's freaking out because it's a full copy of the repo... My solution was to make the source repository itself a direct repo, and then add it as a remote to the bare repo. --[[anarcat]]

diff --git a/doc/todo/git-annex_support.mdwn b/doc/todo/git-annex_support.mdwn
index 2f63663..7821962 100644
--- a/doc/todo/git-annex_support.mdwn
+++ b/doc/todo/git-annex_support.mdwn
@@ -96,4 +96,8 @@ See the [[discussion]] for a followup on that. --[[anarcat]]
 Alternative implementation
 ==========================
 
-An alternative implementation, which remains to be detailed but is mentionned in [[forum/ikiwiki_and_big_files]], is to use the [[underlay]] feature combined with the `hardlink` option to deploy the git-annex'd files. Then git-annex is separate from the base ikiwiki git repo. --[[anarcat]]
+An alternative implementation, which remains to be detailed but is mentionned in [[forum/ikiwiki_and_big_files]], is to use the [[underlay]] feature combined with the `hardlink` option to deploy the git-annex'd files. Then git-annex is separate from the base ikiwiki git repo. See also [[tips/Ikiwiki_with_git-annex__44___the_album_and_the_underlay_plugins]] for an example.
+
+Also note that ikiwiki-hosting has a [patch waiting](https://ikiwiki-hosting.branchable.com/todo/git-annex_support) to allow pushes to work with git-annex. This could potentially be expanded to sync content to the final checkout properly, avoiding some of the problems above (esp. wrt to non-annex bare repos).
+
+Combined with the [[underlay]] feature, this could work very nicely indeed... --[[anarcat]]

Fix XSS in openid selector. Thanks, Raghav Bisht.
diff --git a/debian/changelog b/debian/changelog
index 80dec88..3003b4b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -13,6 +13,9 @@ ikiwiki (3.20150108) UNRELEASED; urgency=medium
   * t/inline.t: accept translations of "Add a new post titled:"
     (Closes: #779365)
 
+  [ Joey Hess ]
+  * Fix XSS in openid selector. Thanks, Raghav Bisht.
+
  -- Joey Hess <id@joeyh.name>  Sat, 24 Jan 2015 23:59:20 -0400
 
 ikiwiki (3.20150107) experimental; urgency=medium
diff --git a/doc/bugs/XSS_Alert...__33____33____33__.html b/doc/bugs/XSS_Alert...__33____33____33__.html
index 24a1a3a..436e3fa 100644
--- a/doc/bugs/XSS_Alert...__33____33____33__.html
+++ b/doc/bugs/XSS_Alert...__33____33____33__.html
@@ -23,3 +23,7 @@ Thank You...!!
 Your Faithfully,
 Raghav Bisht
 raghav007bisht@gmail.com
+
+> Thanks Raghav for reporting this issue. I've fixed it in ikiwiki.
+> 
+> --[[Joey]] 
diff --git a/templates/openid-selector.tmpl b/templates/openid-selector.tmpl
index b6be272..0fd8330 100644
--- a/templates/openid-selector.tmpl
+++ b/templates/openid-selector.tmpl
@@ -23,7 +23,7 @@ $(document).ready(function() {
 		</div>
 		<div id="openid_input_area">
 			<label for="openid_identifier" class="block">Enter your OpenID:</label>
-			<input id="openid_identifier" name="openid_identifier" type="text" value="<TMPL_VAR OPENID_URL>"/>
+			<input id="openid_identifier" name="openid_identifier" type="text" value="<TMPL_VAR ESCAPE=HTML OPENID_URL>"/>
 			<input id="openid_submit" type="submit" value="Login"/>
 		</div>
 		<TMPL_IF OPENID_ERROR>

diff --git a/doc/sandbox.mdwn b/doc/sandbox.mdwn
index 8d413d5..2331caf 100644
--- a/doc/sandbox.mdwn
+++ b/doc/sandbox.mdwn
@@ -18,6 +18,7 @@ pre formated text?
 > This is a blockquote.
 >
 > This is the first level of quoting.
+A block of text
 >
 > > This is a nested blockquote.
 >

diff --git a/doc/bugs/XSS_Alert...__33____33____33__.html b/doc/bugs/XSS_Alert...__33____33____33__.html
new file mode 100644
index 0000000..24a1a3a
--- /dev/null
+++ b/doc/bugs/XSS_Alert...__33____33____33__.html
@@ -0,0 +1,25 @@
+Respected Sir,
+Your website "webconverger.org" is vulnerable to XSS Attack.
+
+Vulnerable Links:
+webconverger.org/ikiwiki.cgi?action=verify&do=signin&openid_identifier=1
+
+How To Reproduce The Vulnerability :
+1. Go to this link : webconverger.org/ikiwiki.cgi?action=verify&do=signin&openid_identifier=1
+2. refresh the page and intercept the http request using "brup suite" then at parameter "openid_identifier=" put xss payload
+3. forward the request
+
+XSS Payload :
+1. "></script><script>prompt(909043)</script>
+2. "></script><script>prompt("XSS Alert...!!! : Hacked By Raghav Bisht")</script>
+3. "></script><script>prompt(document.cookie)</script>
+
+NOTE : Proof of concept is attached.
+
+
+Thank You...!!
+
+
+Your Faithfully,
+Raghav Bisht
+raghav007bisht@gmail.com

diff --git a/doc/users/Boris.mdwn b/doc/users/Boris.mdwn
index a6fa220..eee29a3 100644
--- a/doc/users/Boris.mdwn
+++ b/doc/users/Boris.mdwn
@@ -2,8 +2,8 @@
 
 Boris <a href="mailto:bvogeler@gmail.com">bvogeler@gmail.com</a> has been using ikiwiki for several years now as both a wiki engine for group organizing and documenting and as static site generator for a bunch of sites out there, one example would be [[nb-instrument.com|http://nb-instrument.com]].   
 
-So while apparently coming from the frontend, he never wanted to really learn any of the messy stuff that lingers around in this realm besides HTML and CSS and a little scripting where necessary.   
+So while apparently coming from the web-frontend, he never wanted to really learn any of the messy stuff that lingers around in this realm besides HTML and CSS and a little scripting where necessary.   
 
 He is well aware of the web being an amateurish, crappy place, while he thinks that the internet as such, still can be thought of and be used as "a natural resource" like Alan Kay pointed out.     
 
-To learn to write things from scratch he's currently looking at Yesod and alternative frameworks in Haskell and in Rust, learning Haskell (since it's beautiful) and later on Rust (since it wants to be future-wise) to dig into functional languages for building some future proof applications. Being a studied Marxist and working as a sound engineer, musician and producer, running a small studio in an artists run space, he actually is doing this to be able to show to his small kids how important the understanding of fundamentals is.
+To learn to write things from scratch he's currently looking at Yesod and other frameworks in Haskell and in Rust, learning Haskell (since it's beautiful) and later on Rust (since it wants to be wise) to dig into functional languages for building some future proof applications. As a studied Marxist and working as a sound engineer, musician and producer, running a small studio in an artists run space, he actually is doing this to be able to show to his kids how important the understanding of fundamentals is.

diff --git a/doc/users/Boris.mdwn b/doc/users/Boris.mdwn
index b7a4950..a6fa220 100644
--- a/doc/users/Boris.mdwn
+++ b/doc/users/Boris.mdwn
@@ -6,4 +6,4 @@ So while apparently coming from the frontend, he never wanted to really learn an
 
 He is well aware of the web being an amateurish, crappy place, while he thinks that the internet as such, still can be thought of and be used as "a natural resource" like Alan Kay pointed out.     
 
-To learn to write things from scratch he's currently looking at Yesod and alternative frameworks in Haskell and in Rust, learning Haskell (since it's beautiful) and later on Rust (since it wants to be wise) to dig into functional languages for building some future proof applications. Being a studied Marxist and working as a sound engineer, musician and producer, running a small studio in an artists run space, he actually is doing this to be able to show to his small kids how important the understanding of fundamentals is.
+To learn to write things from scratch he's currently looking at Yesod and alternative frameworks in Haskell and in Rust, learning Haskell (since it's beautiful) and later on Rust (since it wants to be future-wise) to dig into functional languages for building some future proof applications. Being a studied Marxist and working as a sound engineer, musician and producer, running a small studio in an artists run space, he actually is doing this to be able to show to his small kids how important the understanding of fundamentals is.

diff --git a/doc/users/Boris.mdwn b/doc/users/Boris.mdwn
index 1a6f586..b7a4950 100644
--- a/doc/users/Boris.mdwn
+++ b/doc/users/Boris.mdwn
@@ -6,4 +6,4 @@ So while apparently coming from the frontend, he never wanted to really learn an
 
 He is well aware of the web being an amateurish, crappy place, while he thinks that the internet as such, still can be thought of and be used as "a natural resource" like Alan Kay pointed out.     
 
-To learn to write things from scratch he's currently looking at Yesod and alternative frameworks in Haskell and in Rust, learning Haskell (since it's beautiful) and later on Rust (since it wants to be wise) to dig into functional languages for building some future proof applications. Being a studied Marxist and working as a sound engineer, musician and producer, running a small studio in an artists run space, he actually is doing this to be able to show to his small kids how importand the understanding of fundamentals is.
+To learn to write things from scratch he's currently looking at Yesod and alternative frameworks in Haskell and in Rust, learning Haskell (since it's beautiful) and later on Rust (since it wants to be wise) to dig into functional languages for building some future proof applications. Being a studied Marxist and working as a sound engineer, musician and producer, running a small studio in an artists run space, he actually is doing this to be able to show to his small kids how important the understanding of fundamentals is.