Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package perl-Dancer2-Plugin-Auth-Extensible
for openSUSE:Factory checked in at 2026-08-21 17:01:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/perl-Dancer2-Plugin-Auth-Extensible (Old)
and
/work/SRC/openSUSE:Factory/.perl-Dancer2-Plugin-Auth-Extensible.new.1258 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Dancer2-Plugin-Auth-Extensible"
Fri Aug 21 17:01:37 2026 rev:4 rq:1372843 version:0.713.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/perl-Dancer2-Plugin-Auth-Extensible/perl-Dancer2-Plugin-Auth-Extensible.changes
2025-01-17 18:38:26.803627351 +0100
+++
/work/SRC/openSUSE:Factory/.perl-Dancer2-Plugin-Auth-Extensible.new.1258/perl-Dancer2-Plugin-Auth-Extensible.changes
2026-08-21 17:03:11.015008373 +0200
@@ -1,0 +2,21 @@
+Sat Aug 15 05:39:43 UTC 2026 - Tina Müller <[email protected]>
+
+- updated to 0.713.0 (0.713)
+ see /usr/share/doc/packages/perl-Dancer2-Plugin-Auth-Extensible/Changes
+
+ 0.713 Thu 13 Aug 12:00:00 BST 2026
+ [BUG FIXES]
+ * Fix the ability to generate links in emails that have dynamic hosts.
The
+ security fix in the previous release cached the first base URI, which
+ meant that if an application intentionally supports different hosts for
+ its generated emails (based on the reqest host) then these were always
+ fixed at the first request.
+ 0.712 Wed 12 Aug 12:00:00 BST 2026
+ [SECURITY FIXES]
+ * Add uri_base parameter (addresses CVE-2026-15689). If this is not set
and
+ if the application does not otherwise enforce a particular hostname,
then
+ an attacker can generate password reset emails and welcome emails for
+ genuine users that contain links to a malicious host.
+ bsc#1275272
+
+-------------------------------------------------------------------
Old:
----
Dancer2-Plugin-Auth-Extensible-0.711.tar.gz
New:
----
Dancer2-Plugin-Auth-Extensible-0.713.tar.gz
README.md
_scmsync.obsinfo
build.specials.obscpio
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ perl-Dancer2-Plugin-Auth-Extensible.spec ++++++
--- /var/tmp/diff_new_pack.7Z5uoI/_old 2026-08-21 17:03:12.042044736 +0200
+++ /var/tmp/diff_new_pack.7Z5uoI/_new 2026-08-21 17:03:12.047044913 +0200
@@ -1,7 +1,7 @@
#
# spec file for package perl-Dancer2-Plugin-Auth-Extensible
#
-# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2026 SUSE LLC and contributors
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@@ -18,35 +18,38 @@
%define cpan_name Dancer2-Plugin-Auth-Extensible
Name: perl-Dancer2-Plugin-Auth-Extensible
-Version: 0.711.0
+Version: 0.713.0
Release: 0
-# 0.711 -> normalize -> 0.711.0
-%define cpan_version 0.711
+# 0.713 -> normalize -> 0.713.0
+%define cpan_version 0.713
License: Artistic-1.0 OR GPL-1.0-or-later
Summary: Extensible authentication framework for Dancer2 apps
URL: https://metacpan.org/release/%{cpan_name}
Source0:
https://cpan.metacpan.org/authors/id/A/AB/ABEVERLEY/%{cpan_name}-%{cpan_version}.tar.gz
Source1: cpanspec.yml
+Source100: README.md
BuildArch: noarch
BuildRequires: perl
BuildRequires: perl-macros
BuildRequires: perl(Crypt::SaltedHash)
-BuildRequires: perl(Dancer2) >= 0.204000
+BuildRequires: perl(Dancer2) >= 0.204
BuildRequires: perl(Dancer2::Core::Types)
BuildRequires: perl(Dancer2::FileUtils)
BuildRequires: perl(Dancer2::Plugin)
BuildRequires: perl(Dancer2::Template::Tiny)
BuildRequires: perl(DateTime)
BuildRequires: perl(File::Share)
-BuildRequires: perl(File::ShareDir::Install) >= 0.06
+BuildRequires: perl(File::ShareDir::Install) >= 0.60
BuildRequires: perl(HTTP::BrowserDetect)
BuildRequires: perl(HTTP::Cookies)
BuildRequires: perl(HTTP::Request::Common)
+BuildRequires: perl(Mail::Message)
+BuildRequires: perl(Mail::Transport)
BuildRequires: perl(Module::Runtime)
-BuildRequires: perl(Moo) >= 2.000000
+BuildRequires: perl(Moo) >= 2.0
BuildRequires: perl(Moo::Role)
-BuildRequires: perl(Path::Tiny) >= 0.016
-BuildRequires: perl(Plack) >= 1.0029
+BuildRequires: perl(Path::Tiny) >= 0.16
+BuildRequires: perl(Plack) >= 1.2.900
BuildRequires: perl(Plack::Test)
BuildRequires: perl(Session::Token)
BuildRequires: perl(Test::Deep) >= 0.114
@@ -59,7 +62,7 @@
BuildRequires: perl(YAML)
BuildRequires: perl(namespace::clean)
Requires: perl(Crypt::SaltedHash)
-Requires: perl(Dancer2) >= 0.204000
+Requires: perl(Dancer2) >= 0.204
Requires: perl(Dancer2::Core::Types)
Requires: perl(Dancer2::FileUtils)
Requires: perl(Dancer2::Plugin)
@@ -67,9 +70,9 @@
Requires: perl(File::Share)
Requires: perl(HTTP::BrowserDetect)
Requires: perl(Module::Runtime)
-Requires: perl(Moo) >= 2.000000
+Requires: perl(Moo) >= 2.0
Requires: perl(Moo::Role)
-Requires: perl(Plack) >= 1.0029
+Requires: perl(Plack) >= 1.2.900
Requires: perl(Session::Token)
Requires: perl(Try::Tiny)
Requires: perl(URI::Escape)
@@ -84,6 +87,11 @@
Provides: perl(Dancer2::Plugin::Auth::Extensible::Test::App) = %{version}
%undefine __perllib_provides
%{perl_requires}
+# MANUAL BEGIN
+# https://github.com/PerlDancer/Dancer2-Plugin-Auth-Extensible/issues/100
+BuildRequires: sendmail
+BuildRequires: openssl-3
+# MANUAL END
%description
A user authentication and authorisation framework plugin for Dancer2 apps.
@@ -101,7 +109,7 @@
do so, or use the 'slappasswd' utility if you have it installed.
%prep
-%autosetup -n %{cpan_name}-%{cpan_version}
+%autosetup -n %{cpan_name}-%{cpan_version} -p1
%build
perl Makefile.PL INSTALLDIRS=vendor
++++++ Dancer2-Plugin-Auth-Extensible-0.711.tar.gz ->
Dancer2-Plugin-Auth-Extensible-0.713.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Dancer2-Plugin-Auth-Extensible-0.711/Changes
new/Dancer2-Plugin-Auth-Extensible-0.713/Changes
--- old/Dancer2-Plugin-Auth-Extensible-0.711/Changes 2024-08-29
12:28:57.000000000 +0200
+++ new/Dancer2-Plugin-Auth-Extensible-0.713/Changes 2026-08-13
12:50:09.000000000 +0200
@@ -1,5 +1,24 @@
Revision history for Dancer2-Plugin-Auth-Extensible
+0.713 Thu 13 Aug 12:00:00 BST 2026
+
+ [BUG FIXES]
+
+ * Fix the ability to generate links in emails that have dynamic hosts. The
+ security fix in the previous release cached the first base URI, which
+ meant that if an application intentionally supports different hosts for
+ its generated emails (based on the reqest host) then these were always
+ fixed at the first request.
+
+0.712 Wed 12 Aug 12:00:00 BST 2026
+
+ [SECURITY FIXES]
+
+ * Add uri_base parameter (addresses CVE-2026-15689). If this is not set and
+ if the application does not otherwise enforce a particular hostname, then
+ an attacker can generate password reset emails and welcome emails for
+ genuine users that contain links to a malicious host.
+
0.711 Thu 29 Aug 10:28:00 BST 2024
[BUG FIXES]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Dancer2-Plugin-Auth-Extensible-0.711/MANIFEST
new/Dancer2-Plugin-Auth-Extensible-0.713/MANIFEST
--- old/Dancer2-Plugin-Auth-Extensible-0.711/MANIFEST 2024-08-29
12:30:24.000000000 +0200
+++ new/Dancer2-Plugin-Auth-Extensible-0.713/MANIFEST 2026-08-13
13:25:50.000000000 +0200
@@ -18,14 +18,14 @@
t/lib/environments/one-realm.yml
t/lib/environments/provider-config.yml
t/lib/environments/provider-config-extended.yml
+t/lib/environments/uri-base-defined.yml
+t/lib/environments/uri-base-undefined.yml
t/lib/Provider/ConfigExtended.pm
t/lib/Provider/Exploding.pm
t/lib/Provider/NoGetUserDetails.pm
-t/lib/views/.placeholder
t/lib/views/login-without-redirect/custom_login.tt
t/lib/views/login-without-redirect/layouts/main.tt
-t/lib/public/.placeholder
-t/lib/lib/.placeholder
+t/lib/TestApp/Emails.pm
t/manifest.t
t/no-default-pages.t
t/no-get-user-details.t
@@ -36,6 +36,9 @@
t/one-realm.t
t/pod.t
t/pod-coverage.t
+t/return_url.t
+t/uri-base-defined.t
+t/uri-base-undefined.t
lib/Dancer2/Plugin/Auth/Extensible/Provider/Example.pm
lib/Dancer2/Plugin/Auth/Extensible/Provider/Config.pm
lib/Dancer2/Plugin/Auth/Extensible/Provider/Unix.pm
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Dancer2-Plugin-Auth-Extensible-0.711/META.json
new/Dancer2-Plugin-Auth-Extensible-0.713/META.json
--- old/Dancer2-Plugin-Auth-Extensible-0.711/META.json 2024-08-29
12:30:24.000000000 +0200
+++ new/Dancer2-Plugin-Auth-Extensible-0.713/META.json 2026-08-13
13:25:50.000000000 +0200
@@ -4,7 +4,7 @@
"David Precious <[email protected]>"
],
"dynamic_config" : 1,
- "generated_by" : "ExtUtils::MakeMaker version 7.62, CPAN::Meta::Converter
version 2.150010",
+ "generated_by" : "ExtUtils::MakeMaker version 7.70, CPAN::Meta::Converter
version 2.150010",
"license" : [
"perl_5"
],
@@ -66,6 +66,12 @@
"namespace::clean" : "0",
"perl" : "5.006000"
}
+ },
+ "test" : {
+ "requires" : {
+ "Mail::Message" : "0",
+ "Mail::Transport" : "0"
+ }
}
},
"release_status" : "stable",
@@ -79,6 +85,6 @@
},
"x_IRC" : "irc://irc.perl.org/#dancer"
},
- "version" : "0.711",
- "x_serialization_backend" : "JSON::PP version 4.06"
+ "version" : "0.713",
+ "x_serialization_backend" : "JSON::PP version 4.16"
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Dancer2-Plugin-Auth-Extensible-0.711/META.yml
new/Dancer2-Plugin-Auth-Extensible-0.713/META.yml
--- old/Dancer2-Plugin-Auth-Extensible-0.711/META.yml 2024-08-29
12:30:24.000000000 +0200
+++ new/Dancer2-Plugin-Auth-Extensible-0.713/META.yml 2026-08-13
13:25:50.000000000 +0200
@@ -7,6 +7,8 @@
File::ShareDir::Install: '0.06'
HTTP::Cookies: '0'
HTTP::Request::Common: '0'
+ Mail::Message: '0'
+ Mail::Transport: '0'
Path::Tiny: '0.016'
Plack::Test: '0'
Test::Deep: '0.114'
@@ -19,7 +21,7 @@
ExtUtils::MakeMaker: '0'
File::ShareDir::Install: '0.06'
dynamic_config: 1
-generated_by: 'ExtUtils::MakeMaker version 7.62, CPAN::Meta::Converter version
2.150010'
+generated_by: 'ExtUtils::MakeMaker version 7.70, CPAN::Meta::Converter version
2.150010'
license: perl
meta-spec:
url: http://module-build.sourceforge.net/META-spec-v1.4.html
@@ -56,5 +58,5 @@
bugtracker:
https://github.com/PerlDancer/Dancer2-Plugin-Auth-Extensible/issues
homepage: https://github.com/PerlDancer/Dancer2-Plugin-Auth-Extensible/
repository: https://github.com/PerlDancer/Dancer2-Plugin-Auth-Extensible
-version: '0.711'
+version: '0.713'
x_serialization_backend: 'CPAN::Meta::YAML version 0.018'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Dancer2-Plugin-Auth-Extensible-0.711/Makefile.PL
new/Dancer2-Plugin-Auth-Extensible-0.713/Makefile.PL
--- old/Dancer2-Plugin-Auth-Extensible-0.711/Makefile.PL 2024-08-29
12:16:11.000000000 +0200
+++ new/Dancer2-Plugin-Auth-Extensible-0.713/Makefile.PL 2026-08-13
13:12:50.000000000 +0200
@@ -56,6 +56,10 @@
'Plack' => '1.0029', # OO-style Plack::Test
'URI::Escape' => 0,
},
+ TEST_REQUIRES => {
+ 'Mail::Message' => 0,
+ 'Mail::Transport' => 0,
+ },
EXE_FILES => [ 'bin/dancer2-generate-crypted-password' ],
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
clean => { FILES => 'Dancer2-Plugin-Auth-Extensible-*' },
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Dancer2-Plugin-Auth-Extensible-0.711/lib/Dancer2/Plugin/Auth/Extensible/Provider/Base.pm
new/Dancer2-Plugin-Auth-Extensible-0.713/lib/Dancer2/Plugin/Auth/Extensible/Provider/Base.pm
---
old/Dancer2-Plugin-Auth-Extensible-0.711/lib/Dancer2/Plugin/Auth/Extensible/Provider/Base.pm
2024-08-29 12:29:37.000000000 +0200
+++
new/Dancer2-Plugin-Auth-Extensible-0.713/lib/Dancer2/Plugin/Auth/Extensible/Provider/Base.pm
2026-08-13 12:50:34.000000000 +0200
@@ -5,7 +5,7 @@
use warnings;
use Carp;
-our $VERSION = '0.711';
+our $VERSION = '0.713';
croak "Your Dancer2::Plugin::Auth::Extensible provider needs to be
upgraded.\nPlease upgrade to a provider that requires
Dancer2::Plugin::Auth::Extensible v0.6 or greater.\n";
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Dancer2-Plugin-Auth-Extensible-0.711/lib/Dancer2/Plugin/Auth/Extensible/Provider/Config.pm
new/Dancer2-Plugin-Auth-Extensible-0.713/lib/Dancer2/Plugin/Auth/Extensible/Provider/Config.pm
---
old/Dancer2-Plugin-Auth-Extensible-0.711/lib/Dancer2/Plugin/Auth/Extensible/Provider/Config.pm
2024-08-29 12:29:46.000000000 +0200
+++
new/Dancer2-Plugin-Auth-Extensible-0.713/lib/Dancer2/Plugin/Auth/Extensible/Provider/Config.pm
2026-08-13 12:50:40.000000000 +0200
@@ -7,7 +7,7 @@
with "Dancer2::Plugin::Auth::Extensible::Role::Provider";
use namespace::clean;
-our $VERSION = '0.711';
+our $VERSION = '0.713';
=head1 NAME
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Dancer2-Plugin-Auth-Extensible-0.711/lib/Dancer2/Plugin/Auth/Extensible/Provider/Example.pm
new/Dancer2-Plugin-Auth-Extensible-0.713/lib/Dancer2/Plugin/Auth/Extensible/Provider/Example.pm
---
old/Dancer2-Plugin-Auth-Extensible-0.711/lib/Dancer2/Plugin/Auth/Extensible/Provider/Example.pm
2024-08-29 12:29:24.000000000 +0200
+++
new/Dancer2-Plugin-Auth-Extensible-0.713/lib/Dancer2/Plugin/Auth/Extensible/Provider/Example.pm
2026-08-13 12:50:46.000000000 +0200
@@ -11,6 +11,6 @@
=cut
-our $VERSION = '0.711';
+our $VERSION = '0.713';
1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Dancer2-Plugin-Auth-Extensible-0.711/lib/Dancer2/Plugin/Auth/Extensible/Provider/Unix.pm
new/Dancer2-Plugin-Auth-Extensible-0.713/lib/Dancer2/Plugin/Auth/Extensible/Provider/Unix.pm
---
old/Dancer2-Plugin-Auth-Extensible-0.711/lib/Dancer2/Plugin/Auth/Extensible/Provider/Unix.pm
2024-08-29 12:29:30.000000000 +0200
+++
new/Dancer2-Plugin-Auth-Extensible-0.713/lib/Dancer2/Plugin/Auth/Extensible/Provider/Unix.pm
2026-08-13 12:50:26.000000000 +0200
@@ -6,7 +6,7 @@
with "Dancer2::Plugin::Auth::Extensible::Role::Provider";
use namespace::clean;
-our $VERSION = '0.711';
+our $VERSION = '0.713';
=head1 NAME
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Dancer2-Plugin-Auth-Extensible-0.711/lib/Dancer2/Plugin/Auth/Extensible/Role/Provider.pm
new/Dancer2-Plugin-Auth-Extensible-0.713/lib/Dancer2/Plugin/Auth/Extensible/Role/Provider.pm
---
old/Dancer2-Plugin-Auth-Extensible-0.711/lib/Dancer2/Plugin/Auth/Extensible/Role/Provider.pm
2024-08-29 12:30:01.000000000 +0200
+++
new/Dancer2-Plugin-Auth-Extensible-0.713/lib/Dancer2/Plugin/Auth/Extensible/Role/Provider.pm
2026-08-13 12:50:54.000000000 +0200
@@ -4,7 +4,7 @@
use Moo::Role;
requires qw(authenticate_user);
-our $VERSION = '0.711';
+our $VERSION = '0.713';
=head1 NAME
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Dancer2-Plugin-Auth-Extensible-0.711/lib/Dancer2/Plugin/Auth/Extensible/Test/App.pm
new/Dancer2-Plugin-Auth-Extensible-0.713/lib/Dancer2/Plugin/Auth/Extensible/Test/App.pm
---
old/Dancer2-Plugin-Auth-Extensible-0.711/lib/Dancer2/Plugin/Auth/Extensible/Test/App.pm
2024-08-29 12:29:54.000000000 +0200
+++
new/Dancer2-Plugin-Auth-Extensible-0.713/lib/Dancer2/Plugin/Auth/Extensible/Test/App.pm
2026-08-13 12:51:31.000000000 +0200
@@ -6,7 +6,7 @@
=cut
-our $VERSION = '0.711';
+our $VERSION = '0.713';
use strict;
use warnings;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Dancer2-Plugin-Auth-Extensible-0.711/lib/Dancer2/Plugin/Auth/Extensible/Test.pm
new/Dancer2-Plugin-Auth-Extensible-0.713/lib/Dancer2/Plugin/Auth/Extensible/Test.pm
---
old/Dancer2-Plugin-Auth-Extensible-0.711/lib/Dancer2/Plugin/Auth/Extensible/Test.pm
2024-08-29 12:29:15.000000000 +0200
+++
new/Dancer2-Plugin-Auth-Extensible-0.713/lib/Dancer2/Plugin/Auth/Extensible/Test.pm
2026-08-13 12:51:39.000000000 +0200
@@ -1,6 +1,6 @@
package Dancer2::Plugin::Auth::Extensible::Test;
-our $VERSION = '0.711';
+our $VERSION = '0.713';
=head1 NAME
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Dancer2-Plugin-Auth-Extensible-0.711/lib/Dancer2/Plugin/Auth/Extensible.pm
new/Dancer2-Plugin-Auth-Extensible-0.713/lib/Dancer2/Plugin/Auth/Extensible.pm
---
old/Dancer2-Plugin-Auth-Extensible-0.711/lib/Dancer2/Plugin/Auth/Extensible.pm
2024-08-29 12:29:08.000000000 +0200
+++
new/Dancer2-Plugin-Auth-Extensible-0.713/lib/Dancer2/Plugin/Auth/Extensible.pm
2026-08-13 12:50:18.000000000 +0200
@@ -1,11 +1,11 @@
package Dancer2::Plugin::Auth::Extensible;
-our $VERSION = '0.711';
+our $VERSION = '0.713';
use strict;
use warnings;
use Carp;
-use Dancer2::Core::Types qw(ArrayRef Bool HashRef Int Str);
+use Dancer2::Core::Types qw(ArrayRef Bool HashRef Maybe Int Str);
use Dancer2::FileUtils qw(path);
use Dancer2::Template::Tiny;
use File::Share qw(dist_dir);
@@ -175,6 +175,26 @@
plugin_keyword => 1,
);
+has uri_base => (
+ is => 'ro',
+ isa => Maybe[Str],
+ from_config => 1,
+);
+
+# Use the uri_base from the configuration if set, otherwise the one from this
+# particular request. This can potentially generate security vulnerabilities if
+# the calling application allows unsanitised host headers (see pod for
+# uri_base).
+sub uri_base_request
+{ my $plugin = shift;
+ my $base = $plugin->uri_base || $plugin->app->request->uri_base;
+ my $uri = URI->new($base);
+ # Make sure that URI always ends in separator, so that the path can be
+ # appended
+ $uri->path($uri->path =~ s!/*$!/!r);
+ $uri;
+}
+
has user_home_page => (
is => 'ro',
isa => Str,
@@ -1037,7 +1057,7 @@
%message = &{$password_reset_text}( $plugin, %options );
}
else {
- my $site = $plugin->app->request->uri_base;
+ my $link = URI->new_abs("login/$options{code}",
$plugin->uri_base_request);
my $appname = $plugin->app->config->{appname} || '[unknown]';
$message{subject} = "Password reset request";
$message{from} = $plugin->mail_from;
@@ -1045,7 +1065,7 @@
A request has been received to reset your password for $appname. If
you would like to do so, please follow the link below:
-$site/login/$options{code}
+$link
__EMAIL
}
@@ -1103,14 +1123,12 @@
%message = &{$welcome_text}( $plugin, %options );
}
else {
- my $site = $plugin->app->request->base;
- my $host = $site->host;
my $appname = $plugin->app->config->{appname} || '[unknown]';
- my $reset_link = $site . "login/$options{code}";
- $message{subject} = "Welcome to $host";
+ my $reset_link = URI->new_abs("login/$options{code}",
$plugin->uri_base_request);
+ $message{subject} = "Welcome to $appname";
$message{from} = $plugin->mail_from;
$message{plain} = <<__EMAIL;
-An account has been created for you at $host. If you would like
+An account has been created for you at $appname. If you would like
to accept this, please follow the link below to set a password:
$reset_link
@@ -1800,7 +1818,9 @@
Creates a new user, if the authentication provider supports it. Optionally
sends a welcome message with a password reset request, in which case an
-email key must be provided.
+email key must be provided. If sending welcome emails, see the C<uri_base>
+configuration parameter: to prevent an attacker creating malicious links,
+either this must be set or the application must enforce a valid hostname.
This function works in the same manner as L<update_user>, except that
the username key is mandatory. As with L<update_user>, it is recommended
@@ -1853,7 +1873,10 @@
=head2 password_reset_send
L</password_reset_send> sends a user an email with a password reset link. Along
-with L</user_password>, it allows a user to reset their password.
+with L</user_password>, it allows a user to reset their password. See the
+C<uri_base> configuration parameter: to prevent an attacker creating malicious
+links, either this must be set or the application must enforce a valid
+hostname.
The function must be called with the key C<username> and a value that is the
username. The username specified will be sent an email with a link to reset
@@ -2107,6 +2130,16 @@
password_reset_send_email: My::App::reset_send # Customise sending
sub
password_reset_text: My::App::reset_text # Customise reset text
+ # Specify the base hostname for URIs generated by the plugin. By
+ # default this will be lazily-built from a value obtained from
+ # Dancer (which uses the request header supplied by the client).
+ # Because this can be controlled by an attacker, it is recommended
+ # to force the value here, unless your application enforces this
+ # value in other ways (e.g. redirecting within the application in
+ # the event that the specified hostname is unknown). The value
+ # specified here will be coerced into a URI object.
+ uri_base: https://myserver.example.com
+
# create_user options
welcome_send: My::App::welcome_send # Customise welcome email sub
welcome_text: My::App::welcome_text # Customise welcome email text
@@ -2193,6 +2226,12 @@
Called just before the session gets destroyed on logout.
+=head1 SECURITY CONSIDERATIONS
+
+If not used correctly, this module can potentially be abused to insert
+malicious URIs in the emails that it generates. See the documentation for
+uri_base, create_user and password_reset_send.
+
=head1 AUTHOR
David Precious, C<< <davidp at preshweb.co.uk> >>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Dancer2-Plugin-Auth-Extensible-0.711/t/lib/TestApp/Emails.pm
new/Dancer2-Plugin-Auth-Extensible-0.713/t/lib/TestApp/Emails.pm
--- old/Dancer2-Plugin-Auth-Extensible-0.711/t/lib/TestApp/Emails.pm
1970-01-01 01:00:00.000000000 +0100
+++ new/Dancer2-Plugin-Auth-Extensible-0.713/t/lib/TestApp/Emails.pm
2026-08-13 12:24:12.000000000 +0200
@@ -0,0 +1,14 @@
+package TestApp::Emails;
+use Dancer2;
+use Dancer2::Plugin::Auth::Extensible;
+
+get '/send_password_reset' => sub {
+ password_reset_send username => 'dave';
+};
+
+get '/create_user/:username' => sub {
+ my $username = route_parameters->get('username');
+ create_user username => $username, email => '[email protected]',
email_welcome => 1;
+};
+
+1;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Dancer2-Plugin-Auth-Extensible-0.711/t/lib/environments/uri-base-defined.yml
new/Dancer2-Plugin-Auth-Extensible-0.713/t/lib/environments/uri-base-defined.yml
---
old/Dancer2-Plugin-Auth-Extensible-0.711/t/lib/environments/uri-base-defined.yml
1970-01-01 01:00:00.000000000 +0100
+++
new/Dancer2-Plugin-Auth-Extensible-0.713/t/lib/environments/uri-base-defined.yml
2026-08-13 13:10:19.000000000 +0200
@@ -0,0 +1,15 @@
+logger: capture
+plugins:
+ Auth::Extensible:
+ uri_base: "https://genuine.example.com"
+ realms:
+ default:
+ provider: Provider::ConfigExtended
+ users:
+ - user: dave
+ pass: beer
+ name: David
+ mailer:
+ module: Mail::Message
+ options:
+ via: sendmail
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Dancer2-Plugin-Auth-Extensible-0.711/t/lib/environments/uri-base-undefined.yml
new/Dancer2-Plugin-Auth-Extensible-0.713/t/lib/environments/uri-base-undefined.yml
---
old/Dancer2-Plugin-Auth-Extensible-0.711/t/lib/environments/uri-base-undefined.yml
1970-01-01 01:00:00.000000000 +0100
+++
new/Dancer2-Plugin-Auth-Extensible-0.713/t/lib/environments/uri-base-undefined.yml
2026-08-13 13:10:24.000000000 +0200
@@ -0,0 +1,14 @@
+logger: capture
+plugins:
+ Auth::Extensible:
+ realms:
+ default:
+ provider: Provider::ConfigExtended
+ users:
+ - user: dave
+ pass: beer
+ name: David
+ mailer:
+ module: Mail::Message
+ options:
+ via: sendmail
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Dancer2-Plugin-Auth-Extensible-0.711/t/lib/lib/.placeholder
new/Dancer2-Plugin-Auth-Extensible-0.713/t/lib/lib/.placeholder
--- old/Dancer2-Plugin-Auth-Extensible-0.711/t/lib/lib/.placeholder
2024-08-29 12:16:11.000000000 +0200
+++ new/Dancer2-Plugin-Auth-Extensible-0.713/t/lib/lib/.placeholder
1970-01-01 01:00:00.000000000 +0100
@@ -1,6 +0,0 @@
-This directory is empty on purpose, and this file is here solely so that git
-tracks it, as git won't track empty directories (mostly because it doesn't
track
-directories at all, only the files in them).
-
-This otherwise-empty directory is needed to avoid a strange bug on Windows
-systems where Cwd::realpath() croaks if they don't exist.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Dancer2-Plugin-Auth-Extensible-0.711/t/lib/public/.placeholder
new/Dancer2-Plugin-Auth-Extensible-0.713/t/lib/public/.placeholder
--- old/Dancer2-Plugin-Auth-Extensible-0.711/t/lib/public/.placeholder
2024-08-29 12:16:11.000000000 +0200
+++ new/Dancer2-Plugin-Auth-Extensible-0.713/t/lib/public/.placeholder
1970-01-01 01:00:00.000000000 +0100
@@ -1,6 +0,0 @@
-This directory is empty on purpose, and this file is here solely so that git
-tracks it, as git won't track empty directories (mostly because it doesn't
track
-directories at all, only the files in them).
-
-This otherwise-empty directory is needed to avoid a strange bug on Windows
-systems where Cwd::realpath() croaks if they don't exist.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Dancer2-Plugin-Auth-Extensible-0.711/t/lib/views/.placeholder
new/Dancer2-Plugin-Auth-Extensible-0.713/t/lib/views/.placeholder
--- old/Dancer2-Plugin-Auth-Extensible-0.711/t/lib/views/.placeholder
2024-08-29 12:16:11.000000000 +0200
+++ new/Dancer2-Plugin-Auth-Extensible-0.713/t/lib/views/.placeholder
1970-01-01 01:00:00.000000000 +0100
@@ -1,6 +0,0 @@
-This directory is empty on purpose, and this file is here solely so that git
-tracks it, as git won't track empty directories (mostly because it doesn't
track
-directories at all, only the files in them).
-
-This otherwise-empty directory is needed to avoid a strange bug on Windows
-systems where Cwd::realpath() croaks if they don't exist.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/Dancer2-Plugin-Auth-Extensible-0.711/t/return_url.t
new/Dancer2-Plugin-Auth-Extensible-0.713/t/return_url.t
--- old/Dancer2-Plugin-Auth-Extensible-0.711/t/return_url.t 1970-01-01
01:00:00.000000000 +0100
+++ new/Dancer2-Plugin-Auth-Extensible-0.713/t/return_url.t 2026-07-13
10:35:59.000000000 +0200
@@ -0,0 +1,119 @@
+use strict;
+use warnings;
+
+use Test::More tests => 15;
+use Plack::App::URLMap;
+use Plack::Test;
+use HTTP::Request::Common;
+# Need to use URI not URI::URL as URI does not decode the URL parameters
+# (needed to test for correct redirects)
+use URI;
+use URI::QueryParam;
+use HTTP::Cookies;
+
+BEGIN {
+ $ENV{DANCER_CONFDIR} = 't/lib';
+ $ENV{DANCER_ENVIRONMENT} = 'provider-config'; #'return_url';
+}
+
+{
+ package TestApp;
+ use Dancer2;
+ use Dancer2::Plugin::Auth::Extensible;
+
+ get '/restricted' => require_login sub {
+ return "Welcome!";
+ };
+}
+
+# Test double-insertion of mount point (see GH81)
+{
+ my $app = Plack::App::URLMap->new;
+ $app->mount("/mypath" => TestApp->to_app);
+ my $test = Plack::Test->create($app);
+
+ my $res = $test->request(GET '/mypath/restricted');
+ ok($res->code == 302, "Checking response code redirect (302)");
+
+ my $uri = URI->new($res->header('Location'));
+
+ my $jar = HTTP::Cookies->new();
+ my $req = POST $uri, [ username => 'dave', password => 'beer' ];
+ $jar->add_cookie_header($req);
+ $res = $test->request($req);
+ $jar->extract_cookies($res);
+
+ my $n_req = GET $res->header('Location');
+ $jar->add_cookie_header($n_req);
+ ok($n_req->url !~ m#/mypath/mypath/#, "Checking duplicate mount path");
+ $res = $test->request($n_req);
+ ok($res->code == 200, "Checking response code correct (not 404)");
+
+ ok $res->is_success, "POST /login with good password response is OK";
+ is $res->content, "Welcome!", "... and we see our custom response";
+}
+
+# Test simple return_url
+{
+ my $app = Dancer2->runner->psgi_app;
+ my $test = Plack::Test->create($app);
+
+ my $res = $test->request(GET '/restricted');
+ ok($res->code == 302, "Checking response code redirect (302)");
+
+ my $uri = URI->new($res->header('Location'));
+
+ my $req = POST $uri, [ username => 'dave', password => 'beer' ];
+ $res = $test->request($req);
+
+ is($res->header('Location'), 'http://localhost/restricted', "Correct
redirect for simple return_url");
+}
+
+# Test encoding and decoding of return_url
+{
+ my $app = Dancer2->runner->psgi_app;
+ my $test = Plack::Test->create($app);
+
+ my $res = $test->request(GET '/restricted?param1=foobar');
+ ok($res->code == 302, "Checking response code redirect (302)");
+
+ my $uri = URI->new($res->header('Location'));
+
+ my $req = POST $uri, [ username => 'dave', password => 'beer' ];
+ $res = $test->request($req);
+
+ my $uri2 = URI->new($res->header('Location'));
+ is($uri2->path, '/restricted', "Path of redirect is correct");
+ is($uri2->query_param, 1, "Correct number of query parameters");
+ is($uri2->query_param("param1"), "foobar", "Correct number of query
parameters");
+}
+
+# Test for redirect to external URL (should not be possible for security
reasons)
+{
+ my $app = Dancer2->runner->psgi_app;
+ my $test = Plack::Test->create($app);
+
+ my $res = $test->request(GET '/restricted');
+ ok($res->code == 302, "Checking response code redirect (302)");
+
+ my $uri = URI->new($res->header('Location'));
+
+ my $jar = HTTP::Cookies->new();
+ my $req = POST $uri, [ username => 'dave', password => 'beer' ];
+ $jar->add_cookie_header($req);
+ $res = $test->request($req);
+ $jar->extract_cookies($res);
+
+ $req = GET 'http://localhost/restricted';
+ $jar->add_cookie_header($req);
+ $res = $test->request($req);
+ is($res->code, 200, "Check logged in okay");
+
+ $req = GET 'http://localhost/login?return_url=https://metacpan.org/';
+ $jar->add_cookie_header($req);
+ $res = $test->request($req);
+ ok($res->code == 302, "Checking response code correct (not 404)");
+ $uri = URI->new($res->header('Location'));
+ is($uri->host, "localhost", "Checking same hostname on redirect");
+}
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Dancer2-Plugin-Auth-Extensible-0.711/t/uri-base-defined.t
new/Dancer2-Plugin-Auth-Extensible-0.713/t/uri-base-defined.t
--- old/Dancer2-Plugin-Auth-Extensible-0.711/t/uri-base-defined.t
1970-01-01 01:00:00.000000000 +0100
+++ new/Dancer2-Plugin-Auth-Extensible-0.713/t/uri-base-defined.t
2026-08-13 13:13:34.000000000 +0200
@@ -0,0 +1,73 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Plack::Test;
+use HTTP::Request::Common;
+
+# Tests to ensure that uri_base is always used when defined, whatever the host
+# of the request. Needs to be a different test to uri-base-undefined.t as a
+# different config is used.
+
+BEGIN {
+ eval "require Mail::Message";
+ plan skip_all => 'Mail::Message is not installed'
+ if $@;
+
+ eval "require Mail::Transport::Sendmail";
+ plan skip_all => 'Mail::Transport is not installed'
+ if $@;
+
+ $ENV{DANCER_CONFDIR} = 't/lib';
+ $ENV{DANCER_ENVIRONMENT} = 'uri-base-defined';
+
+}
+
+use lib 't/lib';
+use TestApp::Emails;
+
+my $message_sent;
+
+{
+ # Function to catch the content of emails sent
+ no warnings 'redefine';
+ *Mail::Transport::Sendmail::trySend = sub ($@) {
+ my ($mailer, $msg, %options) = @_;
+ $message_sent = $msg;
+ return (1, undef, undef, undef, undef, "queued");
+ };
+}
+
+my $app = Dancer2->runner->psgi_app;
+is(ref $app, 'CODE', 'Got app');
+
+my $test = Plack::Test->create($app);
+my $host = "malicious.example.com";
+
+# Send a password reset email
+{
+ my $req = GET "http://$host/send_password_reset";
+ my $res = $test->request($req);
+
+ is $res->code, 200,
+ "Successful response when requesting password reset";
+
+ like $message_sent->string, qr/\Qgenuine.example.com/, "Password reset
email contains base_uri";
+ unlike $message_sent->string, qr/malicious/, "Password reset email does
not contain malicious host";
+ undef $message_sent;
+}
+
+# Create a user sending a welcome email
+{
+ my $req = GET "http://$host/create_user/$host";
+ my $res = $test->request($req);
+
+ is $res->code, 200,
+ "Successful response when requesting password reset";
+
+ like $message_sent->string, qr/\Qgenuine.example.com/, "Password reset
email contains URL";
+ unlike $message_sent->string, qr/malicious/, "Password reset email does
not contain malicious host";
+ undef $message_sent;
+}
+
+done_testing;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/Dancer2-Plugin-Auth-Extensible-0.711/t/uri-base-undefined.t
new/Dancer2-Plugin-Auth-Extensible-0.713/t/uri-base-undefined.t
--- old/Dancer2-Plugin-Auth-Extensible-0.711/t/uri-base-undefined.t
1970-01-01 01:00:00.000000000 +0100
+++ new/Dancer2-Plugin-Auth-Extensible-0.713/t/uri-base-undefined.t
2026-08-13 13:13:28.000000000 +0200
@@ -0,0 +1,68 @@
+use strict;
+use warnings;
+
+use Test::More;
+use Plack::Test;
+use HTTP::Request::Common;
+
+# Tests to ensure that the host of the request is used to generate links in
+# emails, when uri_base is not defined.
+
+BEGIN {
+ eval "require Mail::Message";
+ plan skip_all => 'Mail::Message is not installed'
+ if $@;
+
+ eval "require Mail::Transport::Sendmail";
+ plan skip_all => 'Mail::Transport is not installed'
+ if $@;
+
+ $ENV{DANCER_CONFDIR} = 't/lib';
+ $ENV{DANCER_ENVIRONMENT} = 'uri-base-undefined';
+}
+
+use lib 't/lib';
+use TestApp::Emails;
+
+my $message_sent;
+
+{
+ # Function to catch the content of emails sent
+ no warnings 'redefine';
+ *Mail::Transport::Sendmail::trySend = sub ($@) {
+ my ($mailer, $msg, %options) = @_;
+ $message_sent = $msg;
+ return (1, undef, undef, undef, undef, "queued");
+ };
+}
+
+my $app = Dancer2->runner->psgi_app;
+is(ref $app, 'CODE', 'Got app');
+
+my $test = Plack::Test->create($app);
+
+# For each host request, the host name should be in the email sent
+foreach my $host (qw/application-host-1.example.com
application-host-2.example.com/)
+{
+ # Send a password reset email
+ my $req = GET "http://$host/send_password_reset";
+ my $res = $test->request($req);
+
+ is $res->code, 200,
+ "Successful response when requesting password reset";
+
+ like $message_sent->string, qr/\Q$host/, "Password reset email contains
URL";
+ undef $message_sent;
+
+ # Create a user sending a welcome email
+ $req = GET "http://$host/create_user/$host";
+ $res = $test->request($req);
+
+ is $res->code, 200,
+ "Successful response when requesting password reset";
+
+ like $message_sent->string, qr/\Q$host/, "Password reset email contains
URL";
+ undef $message_sent;
+}
+
+done_testing;
++++++ README.md ++++++
## Build Results
Current state of perl in openSUSE:Factory is

The current state of perl in the devel project build (devel:languages:perl)

++++++ _scmsync.obsinfo ++++++
mtime: 1787310444
commit: a086d15f70734595ede1745c961b9770ca46573736abcb96c75cbf84ce09a0ca
url: https://src.opensuse.org/perl/perl-Dancer2-Plugin-Auth-Extensible
revision: a086d15f70734595ede1745c961b9770ca46573736abcb96c75cbf84ce09a0ca
projectscmsync: https://src.opensuse.org/perl/_ObsPrj
++++++ build.specials.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/.gitignore new/.gitignore
--- old/.gitignore 1970-01-01 01:00:00.000000000 +0100
+++ new/.gitignore 2026-08-21 13:07:24.000000000 +0200
@@ -0,0 +1 @@
+.osc
++++++ cpanspec.yml ++++++
--- /var/tmp/diff_new_pack.7Z5uoI/_old 2026-08-21 17:03:12.534062156 +0200
+++ /var/tmp/diff_new_pack.7Z5uoI/_new 2026-08-21 17:03:12.543062474 +0200
@@ -11,8 +11,10 @@
# remove-env-perl.patch: -p1
# bar.patch:
# baz.patch: PATCH-FIX-OPENSUSE
-#preamble: |-
-# BuildRequires: gcc-c++
+preamble: |-
+ # https://github.com/PerlDancer/Dancer2-Plugin-Auth-Extensible/issues/100
+ BuildRequires: sendmail
+ BuildRequires: openssl-3
#post_prep: |-
# hunspell=`pkg-config --libs hunspell | sed -e 's,-l,,; s, *,,g'`
# sed -i -e "s,hunspell-X,$hunspell," t/00-prereq.t Makefile.PL