Merge pull request 'Expire inactive sessions, optionally allow to stay signed in' (#82) from feature/8-session_timeouts into master
All checks were successful
continuous-integration/drone/push Build is passing

Reviewed-on: #82
Reviewed-by: galfert <garret.alfert@gmail.com>
This commit is contained in:
Râu Cao 2023-03-31 07:58:24 +00:00
commit 324809f77e
10 changed files with 66 additions and 29 deletions

View File

@ -5,10 +5,4 @@
&:visited { @apply text-indigo-600; }
&:active { @apply text-red-600; }
}
.devise-links {
a {
@apply ks-text-link;
}
}
}

View File

@ -1,6 +1,6 @@
<%= button_tag type: "button", name: "toggle", data: @data,
role: "switch", aria: { checked: @enabled.to_s },
disabled: !@input_enabled,
tabindex: @tabindex, disabled: !@input_enabled,
class: "#{ @enabled ? 'bg-blue-600' : 'bg-gray-200' }
#{ @class_names.present? ? @class_names : '' }
relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer

View File

@ -2,11 +2,12 @@
module FormElements
class ToggleComponent < ViewComponent::Base
def initialize(enabled:, input_enabled: true, data: nil, class_names: nil)
def initialize(enabled:, input_enabled: true, data: nil, class_names: nil, tabindex: nil)
@enabled = !!enabled
@input_enabled = input_enabled
@data = data
@class_names = class_names
@tabindex = tabindex
end
end
end

View File

@ -4,6 +4,10 @@ export default class extends Controller {
static targets = ["buttons", "countdown"]
connect() {
// Devise timeoutable ends up adding a second flash message without content
// TODO investigate bug
if (this.element.textContent.trim() == "true") return;
const timeoutSeconds = parseInt(this.data.get("timeout"));
setTimeout(() => {

View File

@ -38,7 +38,9 @@ class User < ApplicationRecord
devise :ldap_authenticatable,
:confirmable,
:recoverable,
:validatable
:validatable,
:timeoutable,
:rememberable
def ldap_before_save
self.email = Devise::LDAP::Adapter.get_ldap_param(self.cn, "mail").first

View File

@ -7,19 +7,43 @@
<%= f.label :cn, 'User', class: 'block mb-2 font-bold' %>
<p class="flex gap-2 items-center">
<%= f.text_field :cn, autofocus: true, autocomplete: "username",
required: true, class: "relative grow"%>
required: true, class: "relative grow", tabindex: "1" %>
<span class="relative shrink-0 text-gray-500">@ kosmos.org</span>
</p>
</div>
<p>
<p class="mb-8">
<%= f.label :password, class: 'block mb-2 font-bold' %>
<%= f.password_field :password, autocomplete: "current-password",
required: true, class: "w-full"%>
required: true, class: "w-full", tabindex: "2" %>
</p>
<p class="mt-8">
<%= f.submit "Log in", class: 'btn-md btn-blue w-full' %>
<%= tag.div class: "flex items-center mb-8 gap-x-3", data: {
controller: "settings--toggle",
:'settings--toggle-switch-enabled-value' => "false"
} do %>
<div class="relative inline-flex flex-shrink-0">
<%= render FormElements::ToggleComponent.new(
enabled: false, input_enabled: true, class_names: "hidden",
tabindex: "3", data: {
:'settings--toggle-target' => "button",
action: "settings--toggle#toggleSwitch"
}) %>
<%= f.check_box :remember_me, {
checked: false,
data: { :'settings--toggle-target' => "checkbox" }
}, "true", "false" %>
</div>
<%= f.label :remember_me,
class: "text-gray-500 flex flex-col",
data: { action: "click->settings--toggle#toggleSwitch" } %>
<p class="grow text-sm text-right">
<%= link_to "Forgot your password?", new_password_path(resource_name),
class: "text-gray-500 underline" %><br />
</p>
<% end %>
<%= render "devise/shared/links" %>
<p>
<%= f.submit "Log in", class: 'btn-md btn-blue w-full', tabindex: "4" %>
</p>
<% end %>
<% end %>

View File

@ -1,25 +1,29 @@
<div class="devise-links mt-8 text-sm">
<%- if controller_name != 'sessions' %>
<p class="mb-1.5">
<%= link_to "Log in", new_session_path(resource_name) %><br />
<p class="mb-2">
<%= link_to "Log in", new_session_path(resource_name),
class: "text-gray-500 underline" %>
</p>
<% end %>
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
<p class="mb-1.5">
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
<p class="mb-2">
<%= link_to "Forgot your password?", new_password_path(resource_name),
class: "text-gray-500 underline" %>
</p>
<% end %>
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
<p class="mb-1.5">
<%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
<%- if devise_mapping.confirmable? && !controller_name.match(/^(confirmations|sessions)$/) %>
<p class="mb-2">
<%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name),
class: "text-gray-500 underline" %>
</p>
<% end %>
<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
<p class="mb-1.5">
<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
<p class="mb-2">
<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name),
class: "text-gray-500 underline" %>
</p>
<% end %>
</div>

View File

@ -186,13 +186,13 @@ Devise.setup do |config|
# ==> Configuration for :rememberable
# The time the user will be remembered without asking for credentials again.
# config.remember_for = 2.weeks
config.remember_for = 2.weeks
# Invalidates all the remember me tokens when the user signs out.
config.expire_all_remember_me_on_sign_out = true
# If true, extends the user's remember period when remembered via cookie.
# config.extend_remember_period = false
config.extend_remember_period = true
# Options to be passed to the created cookie. For instance, you can set
# secure: true in order to force SSL only cookies.
@ -210,7 +210,7 @@ Devise.setup do |config|
# ==> Configuration for :timeoutable
# The time you want to timeout the user session without activity. After this
# time the user will be asked for credentials again. Default is 30 minutes.
# config.timeout_in = 30.minutes
config.timeout_in = 30.minutes
# ==> Configuration for :lockable
# Defines which strategy will be used to lock an account.

View File

@ -0,0 +1,6 @@
class AddRememberCreatedAtToUsers < ActiveRecord::Migration[7.0]
def change
add_column :users, :remember_created_at, :datetime
add_column :users, :remember_token, :string
end
end

View File

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.0].define(version: 2023_02_23_115536) do
ActiveRecord::Schema[7.0].define(version: 2023_03_19_101128) do
create_table "donations", force: :cascade do |t|
t.integer "user_id"
t.integer "amount_sats"
@ -57,6 +57,8 @@ ActiveRecord::Schema[7.0].define(version: 2023_02_23_115536) do
t.text "ln_login_ciphertext"
t.text "ln_password_ciphertext"
t.string "ln_account"
t.datetime "remember_created_at"
t.string "remember_token"
t.index ["email"], name: "index_users_on_email", unique: true
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end