From baaccc2420b9a33c0d906ac387e67e55d0872086 Mon Sep 17 00:00:00 2001 From: Matthew Kelly Date: Tue, 29 Mar 2022 21:25:31 +0100 Subject: [PATCH] Add support for custom fields on the login page --- docs/Tutorials/Pages.md | 50 +++ docs/images/login_custom.PNG | Bin 0 -> 12199 bytes examples/full_custom_auth.ps1 | 392 ++++++++++++++++++++++ src/Public/Elements.ps1 | 10 +- src/Public/Pages.ps1 | 26 ++ src/Templates/Public/scripts/default.js | 2 +- src/Templates/Views/elements/textbox.pode | 34 +- src/Templates/Views/login.pode | 64 ++-- 8 files changed, 536 insertions(+), 42 deletions(-) create mode 100644 docs/images/login_custom.PNG create mode 100644 examples/full_custom_auth.ps1 diff --git a/docs/Tutorials/Pages.md b/docs/Tutorials/Pages.md index 13e3c1ca..c2e4dc7c 100644 --- a/docs/Tutorials/Pages.md +++ b/docs/Tutorials/Pages.md @@ -39,6 +39,56 @@ Add-PodeAuthIIS -Name Example Set-PodeWebAuth -Authentication Example ``` +### Custom Fields + +By default the Login page will display a login form with Username and Password inputs. This can be overridden by supplying custom Layouts and Elements to the `-Content` parameter of [`Set-PodeWebLoginPage`](../../Functions/Pages/Set-PodeWebLoginPage). Any custom content will be placed between the "Please sign in" message and the "Sign In" button. + +```powershell +# setup sessions +Enable-PodeSessionMiddleware -Duration 120 -Extend + +# define a new custom authentication scheme, which needs a client, username, and password +$custom_scheme = New-PodeAuthScheme -Custom -ScriptBlock { + param($opts) + + # get the client/user/password from the request's post data + $client = $WebEvent.Data.client + $username = $WebEvent.Data.username + $password = $WebEvent.Data.password + + # return the data in a array, which will be passed to the validator script + return @($client, $username, $password) +} + +# now, add a new custom authentication validator using the scheme you created above +$custom_scheme | Add-PodeAuth -Name Example -ScriptBlock { + param($client, $username, $password) + + # check if the client is valid in some database + return @{ + User = @{ + ID ='M0R7Y302' + Name = 'Morty' + Type = 'Human' + } + } + + # return a user object (return $null if validation failed) + return @{ User = $user } +} + +# set the login page to use the custom auth, and also custom login fields +Set-PodeWebLoginPage -Authentication Example -Content @( + New-PodeWebTextbox -Type Text -Name 'client' -Id 'client' -Placeholder 'Client' -Required -AutoFocus -DynamicLabel + New-PodeWebTextbox -Type Text -Name 'username' -Id 'username' -Placeholder 'Username' -Required -DynamicLabel + New-PodeWebTextbox -Type Password -Name 'password' -Id 'password' -Placeholder 'Password' -Required -DynamicLabel +) +``` + +Which would look like below: + +![login_custom](../../images/login_custom.png) + ## Home Every site is setup with a default empty home page. If you choose not to add anything to your home page, then Pode.Web will automatically redirect to the first Webpage. diff --git a/docs/images/login_custom.PNG b/docs/images/login_custom.PNG new file mode 100644 index 0000000000000000000000000000000000000000..335d4887308637b5e1cb1918f36cdd7b5f3dc098 GIT binary patch literal 12199 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 vXsZWw8toat4*wrq>i#dxvD - $(if (!$data.NoForm) { +$( + $controlDivClass = 'form-group row' + if ($data.DynamicLabel) { + $controlDivClass = [string]::Empty + } + if ($data.NoForm) { + $controlDivClass = 'no-form' + } + + "

" +) + + $(if (!$data.NoForm -and !$data.DynamicLabel) { "" }) -
+
$( $element = [string]::Empty @@ -21,6 +32,11 @@ $required = "required" } + $autofocus = [string]::Empty + if ($data.AutoFocus) { + $autofocus = "autofocus" + } + $value = [string]::Empty if (![string]::IsNullOrWhiteSpace($data.Value)) { $value = "value='$($data.Value)'" @@ -30,8 +46,12 @@ $events = ConvertTo-PodeWebEvents -Events $data.Events + if ($data.DynamicLabel) { + "
" + } + if ($data.Multiline) { - $element = "" + $element = "" } else { if ($data.Prepend.Enabled -or $data.Append.Enabled) { @@ -52,7 +72,7 @@ $_type = 'datetime-local' } - $element += "" + $element += "" if ($data.Append.Enabled) { if (![string]::IsNullOrWhiteSpace($data.Append.Text)) { @@ -75,6 +95,10 @@ $element ) + $(if ($data.DynamicLabel) { + "
" + }) + $(if (![string]::IsNullOrWhiteSpace($data.HelpText)) { "$($data.HelpText)" }) diff --git a/src/Templates/Views/login.pode b/src/Templates/Views/login.pode index ed1bfbc2..0cc6e64d 100644 --- a/src/Templates/Views/login.pode +++ b/src/Templates/Views/login.pode @@ -11,48 +11,42 @@
- $(Use-PodeWebPartialView -Path 'shared/scripts' -Data @{ AppPath = $data.AppPath