lesli_shield 1.1.4 → 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/assets/config/lesli_shield_manifest.js +1 -0
- data/app/assets/stylesheets/lesli_shield/application.tailwind.css +2 -0
- data/app/assets/stylesheets/lesli_shield/confirmations.css +18 -18959
- data/app/assets/stylesheets/lesli_shield/passwords.css +18 -18912
- data/app/assets/stylesheets/lesli_shield/registrations.css +24 -18189
- data/app/assets/stylesheets/lesli_shield/sessions.css +1 -18970
- data/app/assets/stylesheets/lesli_shield/sessions.tailwind.css +2 -0
- data/app/controllers/lesli_shield/users_controller.rb +3 -7
- data/app/interfaces/lesli_shield/authentication_interface.rb +3 -3
- data/app/services/lesli_shield/user_registration_service.rb +45 -32
- data/app/services/lesli_shield/user_validator_service.rb +14 -16
- data/app/views/devise/sessions/new.html.erb +36 -32
- data/app/views/devise/shared/_application-devise.html.erb +36 -34
- data/app/views/devise/shared/_demo.html.erb +8 -4
- data/app/views/lesli_shield/users/_information-card.html.erb +35 -45
- data/lib/lesli_shield/engine.rb +6 -0
- data/lib/lesli_shield/version.rb +2 -2
- data/readme.md +112 -49
- metadata +3 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
|
|
2
|
+
@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-content:""}}}@layer theme{:root,:host{--color-amber-50:oklch(98.7% .022 95.277);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-950:oklch(27.9% .077 45.635);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--color-emerald-700:oklch(50.8% .118 165.612);--color-sky-50:oklch(97.7% .013 236.62);--color-sky-200:oklch(90.1% .058 230.902);--color-sky-500:oklch(68.5% .169 237.323);--color-sky-600:oklch(58.8% .158 241.966);--color-sky-700:oklch(50% .134 242.749);--color-sky-800:oklch(44.3% .11 240.79);--color-sky-900:oklch(39.1% .09 240.876);--color-sky-950:oklch(29.3% .066 243.157);--color-rose-50:oklch(96.9% .015 12.422);--color-rose-200:oklch(89.2% .058 10.001);--color-rose-400:oklch(71.2% .194 13.428);--color-rose-500:oklch(64.5% .246 16.439);--color-rose-600:oklch(58.6% .253 17.585);--color-rose-700:oklch(51.4% .222 16.935);--color-slate-50:oklch(98.4% .003 247.858);--color-slate-100:oklch(96.8% .007 247.896);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-300:oklch(86.9% .022 252.894);--color-slate-400:oklch(70.4% .04 256.788);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-600:oklch(44.6% .043 257.281);--color-slate-700:oklch(37.2% .044 257.287);--color-slate-800:oklch(27.9% .041 260.031);--color-slate-900:oklch(20.8% .042 265.755);--color-slate-950:oklch(12.9% .042 264.695);--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-lg:32rem;--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-3xl:1.875rem;--text-3xl--line-height:calc(2.25 / 1.875);--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--leading-tight:1.25;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer utilities{.absolute{position:absolute}.relative{position:relative}.inset-0{inset:0}.inset-x-0{inset-inline:0}.bottom-0{bottom:0}.mx-auto{margin-inline:auto}.mt-1{margin-top:var(--spacing)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mr-1{margin-right:var(--spacing)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-flex{display:inline-flex}.h-5{height:calc(var(--spacing) * 5)}.h-auto{height:auto}.max-h-20{max-height:calc(var(--spacing) * 20)}.min-h-screen{min-height:100vh}.w-5{width:calc(var(--spacing) * 5)}.w-auto{width:auto}.w-full{width:100%}.max-w-\[220px\]{max-width:220px}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.flex-1{flex:1}.grid-cols-\[auto_1fr\]{grid-template-columns:auto 1fr}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing) * 2)}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-y-1{row-gap:var(--spacing)}.overflow-hidden{overflow:hidden}.rounded-lg{border-radius:var(--radius-lg)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-sky-200{border-color:var(--color-sky-200)}.bg-sky-50{background-color:var(--color-sky-50)}.bg-slate-50{background-color:var(--color-slate-50)}.bg-white{background-color:var(--color-white)}.bg-gradient-to-t{--tw-gradient-position:to top in oklab;background-image:linear-gradient(var(--tw-gradient-stops))}.from-slate-950\/70{--tw-gradient-from:#020618b3}@supports (color:color-mix(in lab, red, red)){.from-slate-950\/70{--tw-gradient-from:color-mix(in oklab, var(--color-slate-950) 70%, transparent)}}.from-slate-950\/70{--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.via-slate-900\/10{--tw-gradient-via:#0f172b1a}@supports (color:color-mix(in lab, red, red)){.via-slate-900\/10{--tw-gradient-via:color-mix(in oklab, var(--color-slate-900) 10%, transparent)}}.via-slate-900\/10{--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops)}.to-transparent{--tw-gradient-to:transparent;--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position))}.p-12{padding:calc(var(--spacing) * 12)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-10{padding-block:calc(var(--spacing) * 10)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.text-center{text-align:center}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.leading-tight{--tw-leading:var(--leading-tight);line-height:var(--leading-tight)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.break-all{word-break:break-all}.text-sky-700{color:var(--color-sky-700)}.text-sky-800{color:var(--color-sky-800)}.text-sky-950{color:var(--color-sky-950)}.text-slate-600{color:var(--color-slate-600)}.text-slate-900{color:var(--color-slate-900)}.text-white{color:var(--color-white)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media (hover:hover){.hover\:text-sky-900:hover{color:var(--color-sky-900)}}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-sky-500\/30:focus{--tw-ring-color:#00a5ef4d}@supports (color:color-mix(in lab, red, red)){.focus\:ring-sky-500\/30:focus{--tw-ring-color:color-mix(in oklab, var(--color-sky-500) 30%, transparent)}}.focus\:ring-offset-4:focus{--tw-ring-offset-width:4px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}@media (min-width:40rem){.sm\:px-10{padding-inline:calc(var(--spacing) * 10)}.sm\:pt-8{padding-top:calc(var(--spacing) * 8)}}@media (min-width:64rem){.lg\:col-span-2{grid-column:span 2/span 2}.lg\:block{display:block}.lg\:grid{display:grid}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:px-16{padding-inline:calc(var(--spacing) * 16)}}}@layer components{.lesli-form-field{margin-bottom:calc(var(--spacing) * 4)}.lesli-form-label-wrapper{margin-bottom:calc(var(--spacing) * 2)}.lesli-form-label{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-slate-700);display:block}.lesli-form-field-body{min-width:0}.lesli-form-control{position:relative}.lesli-form-input,.lesli-form-select,.lesli-form-control textarea,.lesli-form-control trix-editor{border-radius:var(--radius-xl);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-slate-300);background-color:var(--color-white);width:100%;padding-inline:calc(var(--spacing) * 3.5);padding-block:calc(var(--spacing) * 2.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-slate-900);--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-outline-style:none;outline-style:none;display:block}:is(.lesli-form-input,.lesli-form-select,.lesli-form-control textarea,.lesli-form-control trix-editor)::placeholder{color:var(--color-slate-400)}@media (hover:hover){:is(.lesli-form-input,.lesli-form-select,.lesli-form-control textarea,.lesli-form-control trix-editor):hover{border-color:var(--color-slate-400)}}:is(.lesli-form-input,.lesli-form-select,.lesli-form-control textarea,.lesli-form-control trix-editor):focus{border-color:var(--color-sky-500);--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);--tw-ring-color:#00a5ef1a}@supports (color:color-mix(in lab, red, red)){:is(.lesli-form-input,.lesli-form-select,.lesli-form-control textarea,.lesli-form-control trix-editor):focus{--tw-ring-color:color-mix(in oklab, var(--color-sky-500) 10%, transparent)}}:is(.lesli-form-input,.lesli-form-select,.lesli-form-control textarea,.lesli-form-control trix-editor):disabled{cursor:not-allowed;background-color:var(--color-slate-100);color:var(--color-slate-500);opacity:.75}.lesli-form-input,.lesli-form-select{height:calc(var(--spacing) * 11)}.lesli-form-control textarea,.lesli-form-control trix-editor{min-height:calc(var(--spacing) * 32);resize:vertical}.lesli-form-select-wrapper{position:relative}.lesli-form-select{cursor:pointer;appearance:none;padding-right:calc(var(--spacing) * 10)}.lesli-form-select-wrapper:after{pointer-events:none;top:50%;right:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 2);width:calc(var(--spacing) * 2);--tw-translate-y:calc(var(--spacing) * -2);translate:var(--tw-translate-x) var(--tw-translate-y);border-right-style:var(--tw-border-style);border-right-width:2px;border-bottom-style:var(--tw-border-style);border-bottom-width:2px;border-color:var(--color-slate-400);--tw-content:"";content:var(--tw-content);position:absolute;rotate:45deg}.lesli-form-checkbox{height:calc(var(--spacing) * 4);width:calc(var(--spacing) * 4);cursor:pointer;border-color:var(--color-slate-300);accent-color:var(--color-sky-600);border-radius:.25rem}.lesli-form-checkbox:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);--tw-ring-color:#00a5ef4d}@supports (color:color-mix(in lab, red, red)){.lesli-form-checkbox:focus{--tw-ring-color:color-mix(in oklab, var(--color-sky-500) 30%, transparent)}}.lesli-form-checkbox:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.lesli-form-checkbox:disabled{cursor:not-allowed;opacity:.5}.lesli-form-checkbox-label{cursor:pointer;align-items:center;gap:calc(var(--spacing) * 2.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--color-slate-600);display:inline-flex}.lesli-form-control.has-icon .lesli-form-input,.lesli-form-control.has-icon .lesli-form-select{padding-left:calc(var(--spacing) * 11)}.lesli-form-icon{pointer-events:none;top:50%;left:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 5);width:calc(var(--spacing) * 5);--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y);color:var(--color-slate-400);justify-content:center;align-items:center;display:inline-flex;position:absolute}.lesli-form-icon .material-symbols-outlined{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height));--tw-leading:1;line-height:1}.lesli-form-help{margin-top:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5);color:var(--color-slate-500)}.lesli-form-field.is-danger .lesli-form-input,.lesli-form-field.is-danger .lesli-form-select,.lesli-form-field.is-danger textarea,.lesli-form-field.is-danger trix-editor{border-color:var(--color-rose-400)}:is(.lesli-form-field.is-danger .lesli-form-input,.lesli-form-field.is-danger .lesli-form-select,.lesli-form-field.is-danger textarea,.lesli-form-field.is-danger trix-editor):focus{border-color:var(--color-rose-500);--tw-ring-color:#ff23571a}@supports (color:color-mix(in lab, red, red)){:is(.lesli-form-field.is-danger .lesli-form-input,.lesli-form-field.is-danger .lesli-form-select,.lesli-form-field.is-danger textarea,.lesli-form-field.is-danger trix-editor):focus{--tw-ring-color:color-mix(in oklab, var(--color-rose-500) 10%, transparent)}}.lesli-form-help.is-danger{color:var(--color-rose-700)}.lesli-form-help.is-warning{color:var(--color-amber-700)}.lesli-form-help.is-success{color:var(--color-emerald-700)}.lesli-form-help.is-info{color:var(--color-sky-700)}.lesli-form-button{height:calc(var(--spacing) * 11);cursor:pointer;justify-content:center;align-items:center;gap:calc(var(--spacing) * 2);border-radius:var(--radius-xl);border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 4);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));border-width:1px;border-color:#0000;display:inline-flex}.lesli-form-button:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(4px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);--tw-outline-style:none;outline-style:none}.lesli-form-button:disabled{pointer-events:none;cursor:not-allowed;opacity:.5}.lesli-form-button.is-primary,.lesli-form-button.is-info{background-color:var(--color-sky-600);color:var(--color-white)}@media (hover:hover){:is(.lesli-form-button.is-primary,.lesli-form-button.is-info):hover{background-color:var(--color-sky-700)}}:is(.lesli-form-button.is-primary,.lesli-form-button.is-info):focus{--tw-ring-color:#00a5ef33}@supports (color:color-mix(in lab, red, red)){:is(.lesli-form-button.is-primary,.lesli-form-button.is-info):focus{--tw-ring-color:color-mix(in oklab, var(--color-sky-500) 20%, transparent)}}.lesli-form-button.is-success{background-color:var(--color-emerald-600);color:var(--color-white)}@media (hover:hover){.lesli-form-button.is-success:hover{background-color:var(--color-emerald-700)}}.lesli-form-button.is-success:focus{--tw-ring-color:#00bb7f33}@supports (color:color-mix(in lab, red, red)){.lesli-form-button.is-success:focus{--tw-ring-color:color-mix(in oklab, var(--color-emerald-500) 20%, transparent)}}.lesli-form-button.is-warning{background-color:var(--color-amber-500);color:var(--color-amber-950)}@media (hover:hover){.lesli-form-button.is-warning:hover{background-color:var(--color-amber-600)}}.lesli-form-button.is-warning:focus{--tw-ring-color:#f99c0033}@supports (color:color-mix(in lab, red, red)){.lesli-form-button.is-warning:focus{--tw-ring-color:color-mix(in oklab, var(--color-amber-500) 20%, transparent)}}.lesli-form-button.is-danger{background-color:var(--color-rose-600);color:var(--color-white)}@media (hover:hover){.lesli-form-button.is-danger:hover{background-color:var(--color-rose-700)}}.lesli-form-button.is-danger:focus{--tw-ring-color:#ff235733}@supports (color:color-mix(in lab, red, red)){.lesli-form-button.is-danger:focus{--tw-ring-color:color-mix(in oklab, var(--color-rose-500) 20%, transparent)}}.lesli-form-button.is-fullwidth{width:100%}.lesli-form-button-icon{height:calc(var(--spacing) * 5);width:calc(var(--spacing) * 5);justify-content:center;align-items:center;display:inline-flex}.lesli-form-button-icon .material-symbols{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height));--tw-leading:1;line-height:1}.lesli-form-fieldset{margin-bottom:calc(var(--spacing) * 6);border-radius:var(--radius-2xl);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-slate-200);background-color:var(--color-white);padding:calc(var(--spacing) * 6);--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.lesli-form-legend{margin-bottom:calc(var(--spacing) * 5);margin-left:calc(var(--spacing) * -1);padding-inline:var(--spacing);font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--color-slate-800)}.lesli-form-fieldset.is-info{border-color:var(--color-sky-200);background-color:#f0f9ff66}@supports (color:color-mix(in lab, red, red)){.lesli-form-fieldset.is-info{background-color:color-mix(in oklab, var(--color-sky-50) 40%, transparent)}}.lesli-form-fieldset.is-success{border-color:var(--color-emerald-200);background-color:#ecfdf566}@supports (color:color-mix(in lab, red, red)){.lesli-form-fieldset.is-success{background-color:color-mix(in oklab, var(--color-emerald-50) 40%, transparent)}}.lesli-form-fieldset.is-warning{border-color:var(--color-amber-200);background-color:#fffbeb80}@supports (color:color-mix(in lab, red, red)){.lesli-form-fieldset.is-warning{background-color:color-mix(in oklab, var(--color-amber-50) 50%, transparent)}}.lesli-form-fieldset.is-danger{border-color:var(--color-rose-200);background-color:#fff1f266}@supports (color:color-mix(in lab, red, red)){.lesli-form-fieldset.is-danger{background-color:color-mix(in oklab, var(--color-rose-50) 40%, transparent)}}@media (min-width:768px){.lesli-form-field.is-horizontal{align-items:flex-start;gap:calc(var(--spacing) * 5);grid-template-columns:minmax(8rem,1fr) minmax(0,3fr);display:grid}.lesli-form-field.is-horizontal>.lesli-form-label-wrapper{padding-top:calc(var(--spacing) * 2.5);text-align:right;margin-bottom:0}.lesli-form-field.is-horizontal>.lesli-form-field-body{grid-column-start:2}}.links{margin-top:calc(var(--spacing) * 5);border-radius:var(--radius-xl);border-style:var(--tw-border-style);border-width:1px;border-color:var(--color-slate-200);background-color:var(--color-white);overflow:hidden}.links>a{align-items:center;gap:calc(var(--spacing) * 3);width:100%;padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--color-slate-700);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));display:flex}@media (hover:hover){.links>a:hover{background-color:var(--color-slate-50);color:var(--color-sky-700)}}.links>a:focus{--tw-outline-style:none;outline-style:none}.links>a:focus-visible{background-color:var(--color-sky-50);--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);--tw-ring-color:#00a5ef4d}@supports (color:color-mix(in lab, red, red)){.links>a:focus-visible{--tw-ring-color:color-mix(in oklab, var(--color-sky-500) 30%, transparent)}}.links>a:focus-visible{--tw-ring-inset:inset}.links>a:not(:last-child){border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--color-slate-200)}.links .icon{height:calc(var(--spacing) * 7);width:calc(var(--spacing) * 7);flex-shrink:0;justify-content:center;align-items:center;margin-right:0;display:inline-flex}.links .icon svg{max-height:calc(var(--spacing) * 6);max-width:calc(var(--spacing) * 6);display:block}.links>a>span:not(.icon){font-family:Domine,OpenSans,sans-serif}.lesli-auth-visual{background-color:#0000;background-image:linear-gradient(#316aff66,#316aff66),url(/lesli_shield/login-background.jpg);background-position:50%;background-repeat:repeat,repeat;background-size:cover;background-attachment:scroll,scroll;background-origin:padding-box,padding-box;background-clip:border-box,border-box}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"<color>";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"<length-percentage>";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"<length-percentage>";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"<length-percentage>";inherits:false;initial-value:100%}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-content{syntax:"*";inherits:false;initial-value:""}
|
|
@@ -41,13 +41,9 @@ module LesliShield
|
|
|
41
41
|
|
|
42
42
|
# GET /users/1
|
|
43
43
|
def show
|
|
44
|
-
@user_roles = @user.
|
|
45
|
-
@activities = @user.
|
|
46
|
-
|
|
47
|
-
.select(:id, :operation, :description, Date2.new.db_column('created_at', as:'date'))
|
|
48
|
-
.limit(7)
|
|
49
|
-
.as_json
|
|
50
|
-
@sessions = @user.result.sessions
|
|
44
|
+
@user_roles = @user.roles
|
|
45
|
+
@activities = @user.logs
|
|
46
|
+
@sessions = @user.sessions
|
|
51
47
|
@user = @user.show
|
|
52
48
|
end
|
|
53
49
|
|
|
@@ -39,13 +39,13 @@ module LesliShield
|
|
|
39
39
|
|
|
40
40
|
# # check if user has an active session
|
|
41
41
|
# if current_session.equal? nil or !current_session.active?
|
|
42
|
-
# current_user.
|
|
42
|
+
# current_user.log(operation: "system_session_logout", description: "session finished by the system")
|
|
43
43
|
# sign_out current_user
|
|
44
44
|
# redirect_to "#{engine_path}/logout" and return
|
|
45
45
|
# end
|
|
46
46
|
|
|
47
47
|
# if !current_session.expiration_at.blank? && current_session.expiration_at < Time.current
|
|
48
|
-
# current_user.
|
|
48
|
+
# current_user.log(operation: "system_session_logout", description: "session expired by the system")
|
|
49
49
|
# sign_out current_user
|
|
50
50
|
# redirect_to "#{engine_path}/logout" and return
|
|
51
51
|
# end
|
|
@@ -53,7 +53,7 @@ module LesliShield
|
|
|
53
53
|
# # check password expiration date
|
|
54
54
|
# if current_user.has_expired_password?
|
|
55
55
|
# unless controller_name == "profiles"
|
|
56
|
-
# current_user.
|
|
56
|
+
# current_user.log(operation: "redirect_due_to_expired_password")
|
|
57
57
|
# redirect_to "/administration/profile#force-password-reset", notice: I18n.t("core.users/sessions.messages_danger_password_expired")
|
|
58
58
|
# return
|
|
59
59
|
# end
|
|
@@ -56,10 +56,44 @@ module LesliShield
|
|
|
56
56
|
|
|
57
57
|
def create_account
|
|
58
58
|
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
add_account() if resource.account.blank?
|
|
60
|
+
add_role() if resource.user_roles.empty?
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
# Synchronize roles for the very first time
|
|
63
|
+
resource.roles.each do |role|
|
|
64
|
+
LesliShield::RolePrivilegeService.new(nil).synchronize(role)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# update user :)
|
|
68
|
+
resource.save
|
|
69
|
+
|
|
70
|
+
# # initialize user dependencies
|
|
71
|
+
# def after_account_assignation
|
|
72
|
+
# return unless self.account
|
|
73
|
+
|
|
74
|
+
# #Courier::One::Firebase::User.sync_user(self)
|
|
75
|
+
# # Lesli::Courier.new(:lesli_calendar).from(:calendar_service, self).create({
|
|
76
|
+
# # name: "Personal Calendar",
|
|
77
|
+
# # default: true
|
|
78
|
+
# # })
|
|
79
|
+
# end
|
|
80
|
+
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
private
|
|
84
|
+
|
|
85
|
+
# check if instance is for multi-account
|
|
86
|
+
ALLOW_MULTI_ACCOUNT = Lesli.config.security.dig(:allow_multiaccount)
|
|
87
|
+
|
|
88
|
+
# This is necessary when user is creating a brand new account
|
|
89
|
+
# and the platform is configured to create new Lesli accounts for every user
|
|
90
|
+
# The platform use the same account when the platform is not saas but
|
|
91
|
+
# proprietary instance (only one company is using the platform)
|
|
92
|
+
# Another scenario where it is not needed to create a new account for the
|
|
93
|
+
# user is when the user is confirming the account through an invitation
|
|
94
|
+
def add_account
|
|
95
|
+
|
|
96
|
+
if ALLOW_MULTI_ACCOUNT === true
|
|
63
97
|
# create new account for the new user only if multi-account is allowed
|
|
64
98
|
account = Lesli::Account.create!({
|
|
65
99
|
user: resource, # set user as owner of his just created account
|
|
@@ -74,42 +108,21 @@ module LesliShield
|
|
|
74
108
|
|
|
75
109
|
# add user to his own account
|
|
76
110
|
resource.account = account
|
|
77
|
-
|
|
78
|
-
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def add_role
|
|
114
|
+
if ALLOW_MULTI_ACCOUNT == true
|
|
79
115
|
# add owner role to user only if multi-account is allowed
|
|
80
116
|
resource.user_roles.create({ role: account.roles.find_by(name: "owner") })
|
|
81
117
|
else
|
|
82
118
|
# Assigning default role if defined in account settings
|
|
83
119
|
# Otherwise, the default role is "limited"
|
|
84
|
-
|
|
85
|
-
default_role_id = Lesli.config.shield.dig(:default_role)
|
|
86
|
-
|
|
87
|
-
if default_role_id.present?
|
|
88
|
-
resource.roles.create({ role: account.roles.find_by(:id => default_role_id)})
|
|
89
|
-
else
|
|
90
|
-
resource.roles.create({ role: account.roles.find_by(name: "limited") })
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
# Synchronize roles for the very first time
|
|
95
|
-
resource.roles.each do |role|
|
|
96
|
-
LesliShield::RolePrivilegeService.new(nil).synchronize(role)
|
|
97
|
-
end
|
|
120
|
+
default_role_name = Lesli.config.shield.dig(:default_role) || "guest"
|
|
98
121
|
|
|
99
|
-
|
|
100
|
-
resource.save
|
|
101
|
-
|
|
102
|
-
# # initialize user dependencies
|
|
103
|
-
# def after_account_assignation
|
|
104
|
-
# return unless self.account
|
|
105
|
-
|
|
106
|
-
# #Courier::One::Firebase::User.sync_user(self)
|
|
107
|
-
# # Lesli::Courier.new(:lesli_calendar).from(:calendar_service, self).create({
|
|
108
|
-
# # name: "Personal Calendar",
|
|
109
|
-
# # default: true
|
|
110
|
-
# # })
|
|
111
|
-
# end
|
|
122
|
+
default_role = resource.account.roles.find_by(name: default_role_name)
|
|
112
123
|
|
|
124
|
+
resource.user_roles.create({ role: default_role })
|
|
125
|
+
end
|
|
113
126
|
end
|
|
114
127
|
end
|
|
115
128
|
end
|
|
@@ -154,10 +154,7 @@ module LesliShield
|
|
|
154
154
|
unless @resource.active? && @resource.locked_until != nil
|
|
155
155
|
|
|
156
156
|
# save a locked log for the requested user
|
|
157
|
-
|
|
158
|
-
title: "session_creation_failed",
|
|
159
|
-
description: "user_locked"
|
|
160
|
-
})
|
|
157
|
+
log_failure("user_locked")
|
|
161
158
|
|
|
162
159
|
return false
|
|
163
160
|
|
|
@@ -172,10 +169,7 @@ module LesliShield
|
|
|
172
169
|
unless @resource.confirmed?
|
|
173
170
|
|
|
174
171
|
# save a invalid credentials log for the requested user
|
|
175
|
-
|
|
176
|
-
title: "session_creation_failed",
|
|
177
|
-
description: "email_not_confirmed"
|
|
178
|
-
})
|
|
172
|
+
log_failure("email_not_confirmed")
|
|
179
173
|
|
|
180
174
|
return false
|
|
181
175
|
|
|
@@ -190,10 +184,7 @@ module LesliShield
|
|
|
190
184
|
# check if user has roles assigned
|
|
191
185
|
if @resource.roles.empty?
|
|
192
186
|
|
|
193
|
-
|
|
194
|
-
title: "session_creation_failed",
|
|
195
|
-
description: "user_has_no_assigned_role"
|
|
196
|
-
})
|
|
187
|
+
log_failure("user_has_no_assigned_role")
|
|
197
188
|
|
|
198
189
|
return true
|
|
199
190
|
|
|
@@ -207,15 +198,22 @@ module LesliShield
|
|
|
207
198
|
|
|
208
199
|
# check user has at least one active role before authorize the sign-in request
|
|
209
200
|
unless (@resource.roles.map {|role| role.active}.include? true)
|
|
210
|
-
|
|
211
|
-
title: "session_creation_failed",
|
|
212
|
-
description: "user_has_no_active_role"
|
|
213
|
-
})
|
|
201
|
+
log_failure("user_has_no_active_role")
|
|
214
202
|
|
|
215
203
|
return false
|
|
216
204
|
end
|
|
217
205
|
|
|
218
206
|
return true
|
|
219
207
|
end
|
|
208
|
+
|
|
209
|
+
def log_failure(description)
|
|
210
|
+
@resource.log(
|
|
211
|
+
engine: LesliShield,
|
|
212
|
+
source: self.class.name,
|
|
213
|
+
action: "validate",
|
|
214
|
+
operation: "session_creation_failed",
|
|
215
|
+
description: description
|
|
216
|
+
)
|
|
217
|
+
end
|
|
220
218
|
end
|
|
221
219
|
end
|
|
@@ -44,59 +44,63 @@ title = I18n.t("overrides.lesli_shield.devise/sessions.view_title",
|
|
|
44
44
|
default: :"lesli_shield.devise/sessions.view_title")
|
|
45
45
|
%>
|
|
46
46
|
|
|
47
|
-
<%= render("devise/shared/application-devise", title:title) do %>
|
|
47
|
+
<%= render("devise/shared/application-devise", title: title) do %>
|
|
48
|
+
|
|
49
|
+
<% authentication_error = flash[:alert].presence || flash[:error].presence %>
|
|
48
50
|
|
|
49
51
|
<%= form_for(
|
|
50
|
-
resource,
|
|
51
|
-
as: resource_name,
|
|
52
|
+
resource,
|
|
53
|
+
as: resource_name,
|
|
52
54
|
url: user_session_path,
|
|
53
55
|
builder: LesliView::Forms::Builder,
|
|
56
|
+
html: { class: "lesli-login-form" },
|
|
54
57
|
data: { turbo: false }
|
|
55
|
-
|
|
58
|
+
) do |form| %>
|
|
56
59
|
|
|
57
60
|
<% if Lesli.config.demo %>
|
|
58
61
|
<%= render("devise/shared/demo") %>
|
|
59
62
|
<% end %>
|
|
60
63
|
|
|
61
|
-
<%= form.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
category:
|
|
65
|
-
icon: "person"
|
|
64
|
+
<%= form.field_control_email(
|
|
65
|
+
:email,
|
|
66
|
+
label: I18n.t("lesli_shield.devise/sessions.label_email", default: "Email address"),
|
|
67
|
+
category: authentication_error.present? ? :danger : nil,
|
|
68
|
+
icon: "person",
|
|
69
|
+
autofocus: true,
|
|
70
|
+
autocomplete: "email",
|
|
71
|
+
required: true,
|
|
72
|
+
placeholder: Lesli.config.company[:email]
|
|
66
73
|
) %>
|
|
67
74
|
|
|
68
|
-
<%= form.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
category:
|
|
73
|
-
icon: "key"
|
|
75
|
+
<%= form.field_control_password(
|
|
76
|
+
:password,
|
|
77
|
+
label: I18n.t("lesli_shield.devise/sessions.label_password", default: "Password"),
|
|
78
|
+
message: authentication_error,
|
|
79
|
+
category: authentication_error.present? ? :danger : nil,
|
|
80
|
+
icon: "key",
|
|
81
|
+
autocomplete: "current-password",
|
|
82
|
+
required: true,
|
|
83
|
+
placeholder: "••••••••"
|
|
74
84
|
) %>
|
|
75
85
|
|
|
76
86
|
<% if params[:r].presence %>
|
|
77
|
-
<%=
|
|
87
|
+
<%= hidden_field_tag "user[redirect]", params[:r] %>
|
|
78
88
|
<% end %>
|
|
79
89
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
<%= I18n.t("lesli_shield.devise/sessions.button_log_in") %>
|
|
86
|
-
</button>
|
|
87
|
-
</div>
|
|
88
|
-
</div>
|
|
90
|
+
<%= form.field_control_button(
|
|
91
|
+
I18n.t("lesli_shield.devise/sessions.button_log_in"),
|
|
92
|
+
{ class: "is-fullwidth" },
|
|
93
|
+
icon: "login"
|
|
94
|
+
) %>
|
|
89
95
|
|
|
90
96
|
<% if Lesli.config.security.dig(:allow_registration) %>
|
|
91
|
-
<p class="
|
|
97
|
+
<p class="mt-1 text-center text-sm text-slate-600">
|
|
92
98
|
<%= I18n.t("lesli_shield.devise/sessions.view_still_not_registered") %>
|
|
93
|
-
<%= link_to(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
</p>
|
|
99
|
+
<%= link_to I18n.t("lesli_shield.devise/sessions.button_create_account"),
|
|
100
|
+
new_user_registration_path %>
|
|
101
|
+
</p>
|
|
97
102
|
<% end %>
|
|
98
|
-
|
|
99
103
|
<% end %>
|
|
100
104
|
|
|
101
|
-
<%= render("devise/shared/links", password_reset:true, magic_link:
|
|
105
|
+
<%= render("devise/shared/links", password_reset:true, magic_link:true, otp:true, login:true) %>
|
|
102
106
|
<% end %>
|
|
@@ -30,46 +30,48 @@ Building a better future, one line of code at a time.
|
|
|
30
30
|
// ·
|
|
31
31
|
%>
|
|
32
32
|
|
|
33
|
-
<% title =
|
|
34
|
-
<% back_to_login =
|
|
33
|
+
<% title = local_assigns.fetch(:title, "") %>
|
|
34
|
+
<% back_to_login = local_assigns.fetch(:back_to_login, false) %>
|
|
35
35
|
|
|
36
|
-
<main id="lesli-application" class="
|
|
37
|
-
<section class="
|
|
38
|
-
|
|
39
|
-
<div class="
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
</span>
|
|
47
|
-
<span>Back to Login</span>
|
|
48
|
-
</span>
|
|
49
|
-
<% end %>
|
|
50
|
-
</div>
|
|
36
|
+
<main id="lesli-application" class="min-h-screen bg-slate-50 lg:grid lg:grid-cols-3">
|
|
37
|
+
<section class="flex min-h-screen flex-col bg-white">
|
|
38
|
+
<% if back_to_login %>
|
|
39
|
+
<div class="px-6 pt-6 sm:px-10 sm:pt-8">
|
|
40
|
+
<%= link_to new_user_session_path,
|
|
41
|
+
class: "inline-flex items-center gap-2 rounded-lg text-sm font-medium text-sky-700 transition hover:text-sky-900 focus:outline-none focus:ring-2 focus:ring-sky-500/30 focus:ring-offset-4" do %>
|
|
42
|
+
<svg class="h-5 w-5" viewBox="0 0 20 20" fill="none" aria-hidden="true">
|
|
43
|
+
<path d="m12.5 15-5-5 5-5" stroke="currentColor" stroke-width="1.75" stroke-linecap="round" stroke-linejoin="round"/>
|
|
44
|
+
</svg>
|
|
45
|
+
<span><%= I18n.t("actions.back_to_login", default: "Back to login") %></span>
|
|
51
46
|
<% end %>
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
<%# Logo container %>
|
|
55
|
-
<div class="logo has-text-centered mb-6">
|
|
56
|
-
<%= image_tag(
|
|
57
|
-
"lesli_assets/brand/app-auth.svg",
|
|
58
|
-
:class => "#{lesli_instance_code}-logo mb-2",
|
|
59
|
-
:alt => "Main logo")
|
|
60
|
-
%>
|
|
61
|
-
<h1 class="is-title is-size-3 has-text-primary">
|
|
62
|
-
<%= title %>
|
|
63
|
-
</h1>
|
|
64
|
-
</div>
|
|
47
|
+
</div>
|
|
48
|
+
<% end %>
|
|
65
49
|
|
|
66
|
-
|
|
50
|
+
<div class="flex flex-1 items-center justify-center px-6 py-10 sm:px-10 lg:px-16">
|
|
51
|
+
<div class="w-full max-w-md">
|
|
52
|
+
<div class="mb-8 text-center">
|
|
53
|
+
<%= image_tag(
|
|
54
|
+
"lesli_assets/brand/app-auth.svg",
|
|
55
|
+
class: "#{lesli_instance_code}-logo mx-auto mb-6 h-auto max-h-20 w-auto max-w-[220px]",
|
|
56
|
+
alt: I18n.t("lesli_shield.authentication.logo_alt", default: "Application logo")
|
|
57
|
+
) %>
|
|
67
58
|
|
|
59
|
+
<% if title.present? %>
|
|
60
|
+
<h1 class="text-3xl font-semibold tracking-tight text-slate-900"><%= title %></h1>
|
|
61
|
+
<% end %>
|
|
68
62
|
</div>
|
|
69
|
-
|
|
70
|
-
|
|
63
|
+
|
|
64
|
+
<%= yield %>
|
|
71
65
|
</div>
|
|
72
66
|
</div>
|
|
73
|
-
<div class="column background is-hidden-touch"></div>
|
|
74
67
|
</section>
|
|
68
|
+
|
|
69
|
+
<aside class="lesli-auth-visual relative hidden min-h-screen overflow-hidden lg:col-span-2 lg:block" aria-hidden="true">
|
|
70
|
+
<div class="absolute inset-0 bg-gradient-to-t from-slate-950/70 via-slate-900/10 to-transparent"></div>
|
|
71
|
+
<div class="absolute inset-x-0 bottom-0 p-12 text-white">
|
|
72
|
+
<p class="max-w-lg text-3xl font-semibold leading-tight">
|
|
73
|
+
<%= I18n.t("lesli_shield.authentication.tagline", default: "A better way to manage your work.") %>
|
|
74
|
+
</p>
|
|
75
|
+
</div>
|
|
76
|
+
</aside>
|
|
75
77
|
</main>
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
|
|
2
|
-
<fieldset class="
|
|
3
|
-
<legend>
|
|
4
|
-
<
|
|
5
|
-
|
|
2
|
+
<fieldset class="mb-8 rounded-xl border border-sky-200 bg-sky-50 px-4 pb-4 text-sm text-sky-950">
|
|
3
|
+
<legend class="px-2 font-semibold text-sky-800">Demo account</legend>
|
|
4
|
+
<dl class="mt-1 grid grid-cols-[auto_1fr] gap-x-3 gap-y-1">
|
|
5
|
+
<dt class="font-medium">Username:</dt>
|
|
6
|
+
<dd class="break-all"><%= Lesli.config.company[:email] %></dd>
|
|
7
|
+
<dt class="font-medium">Password:</dt>
|
|
8
|
+
<dd><%= Lesli.config.security[:password] %></dd>
|
|
9
|
+
</dl>
|
|
6
10
|
</fieldset>
|
|
@@ -1,49 +1,39 @@
|
|
|
1
|
-
<div class="user-information-card
|
|
2
|
-
<div class="
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
</span>
|
|
32
|
-
<%= @user.telephone %>
|
|
33
|
-
</a>
|
|
1
|
+
<div class="user-information-card mt-6 mb-4 flex flex-col items-center gap-4 text-center md:flex-row md:text-left">
|
|
2
|
+
<div class="shrink-0">
|
|
3
|
+
<%= render LesliView::Elements::Avatar.new(
|
|
4
|
+
name: @user.full_name
|
|
5
|
+
) %>
|
|
6
|
+
</div>
|
|
7
|
+
|
|
8
|
+
<div class="min-w-0">
|
|
9
|
+
<h5 class="text-xl font-semibold leading-tight text-slate-800">
|
|
10
|
+
<%= @user.full_name %>
|
|
11
|
+
</h5>
|
|
12
|
+
|
|
13
|
+
<p class="mb-1 text-slate-600"><%= @user.title %></p>
|
|
14
|
+
|
|
15
|
+
<div class="flex flex-wrap items-center justify-center gap-x-4 gap-y-2 md:justify-start">
|
|
16
|
+
<a
|
|
17
|
+
class="inline-flex min-w-0 items-center text-[var(--lesli-color-primary)] hover:underline focus-visible:rounded-sm focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--lesli-color-primary)]"
|
|
18
|
+
href="mailto:<%= @user.email %>"
|
|
19
|
+
>
|
|
20
|
+
<span class="material-symbols mr-2 shrink-0 text-xl" aria-hidden="true">email</span>
|
|
21
|
+
<span class="break-all"><%= @user.email %></span>
|
|
22
|
+
</a>
|
|
23
|
+
|
|
24
|
+
<a
|
|
25
|
+
class="inline-flex items-center text-[var(--lesli-color-primary)] hover:underline focus-visible:rounded-sm focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[var(--lesli-color-primary)]"
|
|
26
|
+
href="tel:<%= @user.telephone %>"
|
|
27
|
+
>
|
|
28
|
+
<span class="material-symbols mr-2 shrink-0 text-xl" aria-hidden="true">phone</span>
|
|
29
|
+
<%= @user.telephone %>
|
|
30
|
+
</a>
|
|
34
31
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
</span>
|
|
41
|
-
</span>
|
|
42
|
-
<%= @user.role_names %>
|
|
43
|
-
</p>
|
|
44
|
-
</div>
|
|
45
|
-
</div>
|
|
46
|
-
</div>
|
|
32
|
+
<!-- Show the max role -->
|
|
33
|
+
<p class="inline-flex items-center text-slate-600" v-if="storeUser.role_names">
|
|
34
|
+
<span class="material-symbols mr-2 shrink-0 text-xl" aria-hidden="true">security</span>
|
|
35
|
+
<%= @user.role_names %>
|
|
36
|
+
</p>
|
|
47
37
|
</div>
|
|
48
38
|
</div>
|
|
49
39
|
</div>
|
data/lib/lesli_shield/engine.rb
CHANGED
|
@@ -34,6 +34,12 @@ module LesliShield
|
|
|
34
34
|
class Engine < ::Rails::Engine
|
|
35
35
|
isolate_namespace LesliShield
|
|
36
36
|
|
|
37
|
+
config.to_prepare do
|
|
38
|
+
unless Lesli::User < LesliShield::UserSecurity
|
|
39
|
+
Lesli::User.include(LesliShield::UserSecurity)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
37
43
|
initializer :lesli_shield do |app|
|
|
38
44
|
|
|
39
45
|
# register assets manifest
|
data/lib/lesli_shield/version.rb
CHANGED